MySQL Query для создания "системы Bump" для форума, который я делаю - PullRequest
1 голос
/ 07 апреля 2009

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

Выберите все идентификаторы потоков из таблицы потоков, упорядочив их по отметке времени (в порядке убывания) самого последнего сообщения (наибольшая отметка времени) с идентификатором потока, равным идентификатору потока каждого потока. Поэтому в основном я хочу пройтись по потокам и заставить MySQL проверить базу данных, скажем, на потоке 0. Затем он проверяет все сообщения, у которых threadID равен 0, и сортирует thread0 на основе наибольшей отметки времени сообщений в thread0. Затем он повторяет это для thread1, thread2 и т. Д. И сортирует их соответственно.

Это вообще возможно? Он предназначен для создания эффекта «системной» форума, когда самая последняя активная тема непрерывно поднимается в верхнюю часть списка, пока тема не исчезнет, ​​а затем опустится до нижней части. Раньше я использовал другую реализацию, где я сохранял метку времени lastActivity в таблице потоков и обновлял ее, когда в поток было отправлено новое сообщение, но этот запрос сделал бы вещи намного более эффективными.

Спасибо большое! Здесь есть две соответствующие таблицы: темы и сообщения. Сообщения имеют поле threadID, в котором хранится идентификатор потока, к которому он принадлежит, а также поле отметки времени. Threads имеет поле threadID, соответствующее идентификатору темы сообщения.

Ответы [ 3 ]

2 голосов
/ 07 апреля 2009

В прошлом у меня работало на MySql. Если вы хотите включить больше информации о каждой нити в запрос, вам нужно добавить столбцы в SELECT и GROUP BY.

.
select thread.threadID, max(comments.modifiedOn) as threadUpdated 
   from thread inner join comments on thread.threadID = comments.threadID 
   group by 1 
   order by 2 desc;

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

2 голосов
/ 07 апреля 2009
SELECT  *
FROM    threads t
LEFT JOIN
        posts p
ON      p.id =
        (
        SELECT  p.id
        FROM    posts pi
        WHERE   pi.threadID = t.threadID
        ORDER BY
                pi.timestamp DESC
        LIMIT 1
        )

Наличие индекса на posts (threadID, timestamp) значительно улучшит этот запрос.

Обратите внимание, что в отличие от GROUP BY решений, этот запрос также выбирает все поля из posts и работает, даже если у вас есть дубликаты на последних posts.timestamp.

0 голосов
/ 07 апреля 2009
SELECT t.*, p1.`timestamp`
FROM threads t 
  JOIN posts p1 ON (p1.threadid = t.id)
  LEFT JOIN posts p2 ON (p2.threadid = t.id 
    AND p1.`timestamp` < p2.`timestamp`)
WHERE p2.threadid IS NULL
ORDER BY p1.`timestamp` DESC;
...