Группировка и сортировка вопроса

У меня есть система уведомлений (на основе PHP, MySQL), и я пытаюсь сделать следующее: Результаты уведомлений о запросах сгруппированы по сообщениям без каких-либо ограничений, но затем упорядочены по time_sent, ограниченному 5 (для каждой итерации). Затем я использовал ajax, чтобы показать следующий набор итераций из 5 уведомлений.

В основном мне нужно 5 уведомлений за раз (за набор), но для каждого из них, если группа касается одного сообщения: может быть столько уведомлений, сколько нужно:

Вот как там будет отображаться:

  1. Уведомление о сообщении F - отправлено 1 день назад
  2. Первое уведомление о посте C - отправлено 2 дня назад
    • Второе уведомление о посте C - отправлено 3 дня назад
    • Третье уведомление о посте C - отправлено 4 дня назад
    • Четвертое уведомление о посте C - отправлено 5 дней назад
  3. Уведомление о посте Y - отправлено 3 дня назад
  4. Первое уведомление о посте D - отправлено 4 дня назад
    • Второе уведомление о посте D - отправлено 5 дней назад
    • Третье уведомление о посте D - отправлено 6 дней назад
  5. Уведомление о посте Y - отправлено 5 дней назад

Если бы новое сообщение было отправлено в отношении сообщения Y, оно, естественно, было бы поднято вверх по списку.

Вот как я начал, прежде чем решил внедрить эту групповую систему:

$notifications_req = mysql_query('SELECT * FROM notifications WHERE user_id = "'.$user_id.'" ORDER BY time_sent DESC LIMIT 5');

А теперь я заблудился и боролся с этой группой по порядку и по логике.

База данных содержит, конечно, post_id колонка.

РЕДАКТИРОВАТЬ:

В итоге я довольно резко изменил способ сортировки уведомлений. Вот как я в итоге это сделал. Это может быть не самым эффективным, но работает так, как я хочу:

<?php  $notifications_all_req = mysql_query('SELECT * FROM notifications WHERE user_id = "'.$user_id.'" ORDER BY time_sent DESC');  if(mysql_num_rows($notifications_all_req) > 0){
while($row =  mysql_fetch_assoc($notifications_all_req))
{
    $post_req_ids[] = $row['post_id'];
}
$unique_post_ids = array_unique($post_req_ids);
foreach ($unique_post_ids as $i => $unique_post_id)
{
    ?>      
    <ul id="notifications_ul_<?php echo $i; ?>">
    <?php
    $notifications_req = mysql_query('SELECT * FROM notifications WHERE (user_id = "'.$user_id.'" AND post_id = "'.$unique_post_id.'") ORDER BY time_sent DESC ');
        while($notification =  mysql_fetch_assoc($notifications_req))
        {

        }
        ?>
    </ul>
    <?php
}  }  ?>

Таким образом, я могу контролировать пределы обеих групп уведомлений (используя $i) и те, что в каждой группе, также с Ajax загружают больше кода для последней.

1 ответ

Вы не хотите использовать GROUP BY здесь, потому что это для сводных запросов.

Совет: не используйте SELECT *, Вместо этого выберите нужные столбцы по имени.

Совет профессионала: люди советуют вам использовать PDO или mysqli_ по очень веской причине. Интерфейс mysql_ небезопасен. Если вы поместите веб-приложение, основанное на mysql_, в общедоступной сети, вам придет в голову какой-нибудь злодей. Если вы не возражаете против того, чтобы вас забили, например, если вы создаете прототип или веб-сайт с проверкой концепции, не беспокойтесь об этом.

Давайте получим порядок набора результатов прямо перед тем, как начнем сегментировать его на пять столбцов. Вам нужно два предмета в вашем ORDER BY пункт. Кажется, вы хотите, чтобы ваш набор результатов был упорядочен следующим образом.

SELECT * 
  FROM notifications 
 WHERE user_id = ? 
 ORDER BY post_id, time_sent DESC

Попробуйте, без LIMIT 5и отладьте ваш php-код, чтобы вы получили хорошее отображение, даже если оно слишком длинное для ваших целей.

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

Таким образом, мы должны найти способ получать пять сообщений одновременно. Этот подзапрос сделает это, предоставив список из пяти значений post_id.

 SELECT DISTINCT post_id
   FROM notifications
  WHERE user_id = ?
  ORDER BY post_id
  LIMIT 5 OFFSET ?   

Параметр для OFFSET ? должно быть 0, 5, 10 и т. д., чтобы получить первый, второй, третий и т. д. пакет из пяти сообщений. Если вы хотите только первые пять постов, просто опустите OFFSET пункт.

Теперь нам нужно внедрить этот подзапрос, который получает только пять сообщений в другом запросе, чтобы получить все данные. Это работает так.

SELECT * 
  FROM notifications 
 WHERE post_id IN (
                      SELECT DISTINCT post_id
                        FROM notifications
                       WHERE user_id = ?
                       ORDER BY post_id
                       LIMIT 5 OFFSET ?   
                  ) 
 ORDER BY post_id, time_sent DESC

Этот последний, более сложный SQL-запрос даст набор результатов, который выглядит как первый оператор. Вы должны иметь возможность подключить его к отлаженному php-коду и получить нужный вам дисплей.

Другие вопросы по тегам