Таблицы
форумы
тем
- thread_id
- forum_id
- user_id
- добавлено_ts
thread_replies
- thread_reply_id
- thread_id
- user_id
- добавлено_10
пользователи
Проблема
Я хочу вернуть список форумов с самым последним сообщением для каждого.Эффективно.Отчасти проблема в том, что сообщения распределяются между потоками и thread_replies.
Мой первый инстинкт - получить UNION потоков и thread_replies с нужными мне данными:
SELECT * FROM ((SELECT forum_id, thread_id, user_id, added_ts FROM threads t)
UNION (SELECT t1.forum_id, r.thread_id, r.user_id, r.added_ts FROM thread_replies r
INNER JOIN threads t1 ON t1.thread_id = r.thread_id)) messages;
Now I 'у нас есть список всех сообщений с forum_id, thread_id, user_id и Added_ts.Следующим моим инстинктом было присоединение к этой таблице в таблице форумов, но я не вижу четкого способа свести это значение к последнему значению add_ts для каждого форума, в то же время возвращая оставшиеся необходимые данные.
SELECT * FROM forums f
INNER JOIN
(SELECT messages.*, users.username FROM
((SELECT forum_id, thread_id, user_id, added_ts FROM threads t)
UNION
(SELECT t1.forum_id, r.thread_id, r.user_id, r.added_ts
FROM thread_replies r
INNER JOIN threads t1 ON t1.thread_id = r.thread_id)) messages
INNER JOIN users ON messages.user_id = users.user_id
ORDER BY messages.added_ts) last_replies ON last_replies.forum_id = f.forum_id;
Я пробовал GROUP BY forum_id в сочетании с MAX (last_replies.added_ts), но это только два поля результирующего набора, которые я могу выбрать, используя функции group by и агрегатные функции, насколько я могу судить.
SELECT f.forum_id, MAX(last_replies.added_ts)
FROM forums f
INNER JOIN (
SELECT messages.*, users.username
FROM (
(SELECT forum_id, thread_id, user_id, added_ts
FROM threads t)
UNION
(SELECT t1.forum_id, r.thread_id, r.user_id, r.added_ts
FROM thread_replies r
INNER JOIN threads t1 ON t1.thread_id = r.thread_id)) messages
INNER JOIN users ON messages.user_id = users.user_id
ORDER BY messages.added_ts
) last_replies ON last_replies.forum_id = f.forum_id GROUP BY f.forum_id;
Я думаю, что мог бы быть способ сделать это, используя ORDER BY add_ts DESC и LIMIT 1, но я также не могу понять, как заставить это работать.Я надеюсь получить здесь несколько хороших идей, которые могут направить меня в правильном направлении.
Решение
Основываясь на выбранном ниже решении, я сформулировал этот запрос:
SELECT f.*, last_replies.*, u.username
FROM forums f
INNER JOIN (
SELECT DISTINCT ON (messages.forum_id) messages.*
FROM (
(SELECT forum_id, thread_id, user_id, added_ts FROM threads t)
UNION
(SELECT t1.forum_id, r.thread_id, r.user_id, r.added_ts FROM thread_replies r INNER JOIN threads t1 ON t1.thread_id = r.thread_id)
) messages
ORDER BY messages.forum_id, messages.added_ts DESC
) last_replies ON last_replies.forum_id = f.forum_id
INNER JOIN users u ON last_replies.user_id = u.user_id;