Использование PHP для группировки и отображения записей MySQL по неделям - PullRequest
0 голосов
/ 10 января 2010

Я строю сайт с несколькими «однострочниками». Они добавляются с помощью простой формы PHP5, хранящейся в базе данных MySQL 5. Каждая строка имеет «id» (auto_increment), «title», «description», «status» (1 или 0) и «date_added» (MySQL datetime).

Я хочу отобразить их сгруппированные по месяцам и годам, например:

<dl>
    <dt>August 2009</dt>
    <dd><strong>title 1</strong> - description 1</dd>
    <dd><strong>title 2</strong> - description 2</dd>
    <dd><strong>title 3</strong> - description 3</dd>         
    etc...
</dl>
    <dl>
    <dt>July 2009</dt>
    <dd><strong>title 1</strong> - description 1</dd>
    <dd><strong>title 2</strong> - description 2</dd>
    <dd><strong>title 3</strong> - description 3</dd>         
    etc...
</dl>

Я нашел фрагмент MySQL, который якобы группирует строки по месяцам, однако запрос возвращает только пару результатов, а не полную таблицу:

SELECT `title`, `description`, `date_added`
FROM one_liners WHERE `status`=1 GROUP BY MONTH(date_added)

Как бы я сгруппировал их, а затем зациклил их, как показано выше?

Любая помощь будет принята с благодарностью.

Спасибо!

Ответы [ 3 ]

2 голосов
/ 10 января 2010

Вы не хотите использовать для этого предложение GROUP BY. Хотя это «звучит» так, как вы хотите, оно имеет совершенно иное значение.

Выполнить обычный запрос:

SELECT `title`, `description`, `date_added` FROM one_liners 
WHERE `status`= 1 ORDER BY `date_added`

Затем зациклите результаты, выполнив что-то вроде этого:

$query = 'SELECT `title`, `description`, `date_added` FROM one_liners WHERE `status`= 1 ORDER BY `date_added`';
$res = mysql_query( $query );
$month = null;
$year  = null;

echo '<dl>';
while($row = mysql_fetch_assoc( $res ){
  $r_month = strtotime( $row['date_added'] );
  if($month != date('m', $r_month) || $year != date('Y', $r_month)){
     echo '<dt>' . date('F Y', $r_month) . '</dt>';
     $month = date('m', $r_month);
     $year  = date('Y', $r_month);
  }
  echo '<dd><strong>' . htmlentities( $row['title'] ) . '</strong> &mdash;' . htmlentities( $row['description'] ) . '</dd>';
}
echo '</dl>';

Я специально решил использовать только один dl, потому что dl должен содержать много элементов dd и dt, а не только одну пару в списке. Не стесняйтесь корректировать мой код по мере необходимости, если вы не согласны:)

1 голос
/ 10 января 2010

Я думаю, вам нужно будет сделать это только на PHP. Группирование в SQL обычно используется для таких вещей, как SUM, AVG, MAX, MIN, COUNT и т. Д. Он не влияет на фактический набор записей, чтобы показать какую-то группировку, к которой вы можете обращаться в PHP.

То, что я сделал в подобных ситуациях, - это переменная, которую нужно отслеживать в цикле, чтобы узнать, когда я попаду в новую группу. Для вашего SQL вы сделаете:

SELECT `title`, `description`, `date_added`
FROM one_liners WHERE `status`=1 ORDER BY MONTH date_added DESC

Тогда в PHP вы сделаете:

$prevMonth = '';
while ($row = mysql_fetch_assoc($result)) {
    $currMonth = $row['date_added'];
    if ($currMonth != $prevMonth) {
        if ($prevMonth != '') {
            echo '</dl>';
        }
        echo '<dl><dt>' . $currMonth . '</dt>';
        $prevMonth = $currMonth;
    }
    echo '<dd><strong>' . $row['title'] . '</strong>';
    echo ' - ' . $row['description'] . '</dd>';
}
if (mysql_num_rows($result) > 0) {
        echo '</dl>';
}

Все это действительно делает это, отслеживая месяц из предыдущей строки, пока вы просматриваете цикл. Когда вы доберетесь до нового, он закроет старый DL и откроет новый.

В зависимости от того, как вы храните свои даты в БД (отметка времени или дата / время), вам нужно заменить $currMonth = $row['date_added']; на соответствующий код, чтобы преобразовать его в формат «август 2009» или что вы хотите.

0 голосов
/ 10 января 2010

Вы не хотите использовать GROUP BY там, попробуйте вместо этого ORDER BY.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...