例如,我有这样的消息sql表:
Id from_user_id to_user_id message 1 1 2 Hello 2 1 2 How are you? 3 1 3 Where are you?
查询SELECT DISTINCT to_user_id FROM messages;它返回
to_user_id 2 3
但是,这还不够。我需要向其他用户显示from_user_id(id = 1)的所有最后消息,并避免N + 1查询问题。结果必须像这样
Id from_user_id to_user_id message 2 1 2 How are you? 3 1 3 Where are you?
答案 0 :(得分:1)
你想要自我加入:
SELECT m.*
FROM messages m
LEFT JOIN messages _m ON m.to_user_id = _m.to_user_id
AND _m.id > m.id
WHERE _m.id IS NULL
答案 1 :(得分:1)
您可以使用分析函数排名,并在组中对其进行排序...
select * from (
select id,
from_user_id,
to_user_id,
message,
rank () over (partition by from_user_id, to_user_id order by id desc) rnk
from table_name
) t1 where rnk = 1
这假设id列是顺序生成的数字,因此在id为2的消息之后创建了id为3的消息。通常,如果你有一个timestamp列,它将更符合逻辑。在这种情况下,您可以使用order by timestamp desc
答案 2 :(得分:1)
Postgres提供distinct on
,这通常是解决此类问题的最佳方式:
select distinct on (to_user_id) m.*
from messages m
where m.from_user_id = 1
order by to_user_id, id desc;