我试图从数据库中获取对话列表,并且我希望最近显示的消息与它们一起显示。我无法找到允许我这样做的查询(而且不是N + 1)。
我有这些表格:
chats(id, user_id, post_id, created_at)
messages(id, user_id, chat_id, body, created_at)
我有一个这样的疑问:
select chats.id, chats.user_id, m.latest from chats
inner join (
select chat_id, max(created_at) as latest from messages
group by chat_id
) as m on m.chat_id = chats.id;
但是我想从与max(created_at)
结果对应的行中添加消息正文。是否有可能获得这样的相关专栏?
答案 0 :(得分:3)
使用标准SQL,可以使用窗口函数完成(参见sagi的答案)。
使用Postgres,专有distinct on()
通常比使用窗口函数的等效解决方案更快:
select chats.id, chats.user_id, m.body, m.latest
from chats
join (
select distinct on (chat_id) chat_id, body, created_at as latest
from messages
order by chat_id, created_at desc;
) as m on m.chat_id = chats.id;
使用窗口函数的解决方案更灵活。您也可以使用该消息获取最新的两条(或三条或者......)消息,而distinct on()
只能获得一条消息。
答案 1 :(得分:2)
尝试使用ROW_NUMBER()
:
select chats.id, chats.user_id, m.body from chats
inner join (
select chat_id,body ,
row_number() OVER(PARTITION BY chat_id ORDER BY created_at DESC) as rnk
from messages
) m on m.chat_id = chats.id and m.rnk = 1;