2010-01-10 2 views
0

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

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

<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) 

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

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

Спасибо!

+0

Для nitpick используйте вложенные упорядоченные списки вместо DL/DT для семантической доброты;) Это не определения. – Parrots

ответ

2

Вы не хотите использовать для этого пункт 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 элементы, а не только одна пара в списке. Не стесняйтесь приспосабливать мой код при необходимости, если вы не согласны :)

+0

Это абсолютно идеально *, большое вам спасибо. И, как ни странно, я был в постели прошлой ночью, обдумывая это и понял, что я тупо положил их в 2 DL - я знал, что меня возьмут на себя! Опасности в работе. Но спасибо за отличное решение. * Сохраните недостающую конечную скобку после утверждения while! – user247335

1

Я думаю, вам нужно будет сделать это только на 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 и откроет новый.

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

0

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