PHP / mysql: как мне отображать записи, отсортированные по времени и сгруппированные по дате?

Мне нужно отображать записи, сгруппированные по дате, и отсортировать их по времени. В таблице mysql у меня есть поле с именем entry_time котором хранятся значения php time() . Любые идеи, что было бы самым компактным и простым способом сделать это?

Пример: Мне нужен дисплей:

 21st April 3:00 pm 3:50 pm 22 April 5:00 am 4:00 pm 

Грубый полу-псевдокод:

 $records = /* SELECT * FROM `records` ORDER BY `entry_time` */; $date = null; foreach ($records as $record) { $currentDate = date('Ymd', $record['entry_time']); if ($currentDate != $date) { printf('<h1>%s</h1>', date('Ym-d', $record['entry_time'])); } $date = $currentDate; echo date('H:i', $record['entry_time']); } 

Если вы обрабатываете результаты запроса с помощью PHP, попробуйте написать простой запрос для сортировки записей по дате:

 SELECT NameOfMyThing, MyDateField FROM MyTable ORDER BY MyDateField DESC 

Затем используйте PHP для чтения результатов:

 $last_day = ''; while ($row = $query_result->fetch()) { $date = new DateTime($row->['MyDateField']); $day = $date->format('j F'); // '9 April' $time = $date->format('g:i a'); // '9:05 am' if ($day != $last_day) { print $day . "\n"; $last_day = $day; } print $time . " " . $row->['NameOfMyThing']; } 

Идея здесь – запомнить последний день, когда вы видели, и выводить только дату, когда меняется день.

(Код не проверен, оптимизирован только для чтения).

Имейте многомерный массив.

 $datetime = array("April 21st" => array("5:00a.m", "4:00p.m"), "April 22nd" => array(...)); 

Затем вы можете сортировать по дате и времени отдельно.

Когда у вас есть time() хранящееся в базе данных, самый простой способ:

  1. Сортировка таблицы по столбцу со time() .
  2. Запрос для каждой метки времени из таблицы (я предполагаю, что вам нужны только даты и время).
  3. Для каждой строки результата дважды указывайте date() : один раз в день и месяц, один за час. Имейте последнюю использованную дату, и если они такие же, поставьте следующий раз на тот же элемент массива, что и приговор (я предполагаю, что вы используете решение LainIwakura для хранения таких данных).
  4. Отобразите его так, как вы хотите.

Подобный sql-запрос (используя WordPress в качестве примера) предоставит вам записи в правильном порядке и будет иметь правильное форматирование:

 select date_format(post_date, "%d %b") as day, date_format(post_date, "%T") as time from wp_posts; 

Затем вы можете перебирать этот массив и начинать новый заголовок «день» всякий раз, когда изменяется первый столбец.

Я бы действительно не рекомендовал запрашивать db по одной строке за раз, как было предложено комментарием @ Lainlwakura: PHP медленный, итерация по однострочным запросам медленная. Сортировка массива PHP, особенно в строковых ключах, невероятно медленная. Если вы публикуете записи, охватывающие год или около того, этот подход не будет работать.

Пусть mysql сделает столько, сколько вы можете.

Я мог бы думать слишком легко, но думаю, что это можно сделать с помощью:

 SELECT DATE(`datefield`) `date`, TIME(`datefield`) `time` FROM `yourtable` ORDER BY `datefield` ASC; 

А потом просто покажите его с помощью PHP. MySQL предназначен только для получения данных, а не для его отображения. 🙂

Протестировано и установлено, что оно работает:

 <?php $query = mysql_query("SELECT entry_time FROM the_table ORDER BY entry_time"); // ORDER BY MATTERS! $ts_prev = 0; while ($row = mysql_fetch_assoc($query)) { $ts_curr = strtotime(date("Ymd 00:00:00", $row["entry_time"])); // zero out the time portion if($ts_prev != $ts_curr) { $ts_prev = $ts_curr; echo "<br>\n"; echo date("jS F", $row["entry_time"]); // 21st April echo "<br>\n"; } echo date("h:ia", $row["entry_time"]); // 02:06 pm echo "<br>\n"; } 

запрос:

 SELECT DATE_FORMAT( entry_time, '%D %M' ) as date, GROUP_CONCAT( DATE_FORMAT( entry_time, '%h:%i %p' ) ORDER BY entry_time ASC SEPARATOR '<br />' ) as times FROM yourtable GROUP BY DATE( entry_time ) ORDER BY entry_time 

результаты:

 > date times > 21st April 3:00 PM<br />3:50 PM > 22st April 5:00 AM<br />4:00 PM 

то вы можете пройти через это:

 foreach($result as $row) { echo $row->date. '<br />'. $row->times. '<br />'; } 

edit: преимущество в том, что вся сортировка и форматирование выполняется в движке mysql, поэтому вы можете отображать результат

edit2: Этот запрос даст вам точно результат, который вы хотите:

 SELECT CONCAT( DATE_FORMAT( entry_time, '%D %M' ), "<br />\n", GROUP_CONCAT( DATE_FORMAT( entry_time, '%h:%i %p' ) ORDER BY entry_time ASC SEPARATOR '<br />' ), "<br /><br />\n" ) as dates FROM yourtable GROUP BY DATE( entry_time ) ORDER BY entry_time 

используйте foreach (или любую другую функцию массива), чтобы пройти через нее:

foreach($result as $row) { echo $row->dates; }