Sql 查询 distinct + 其他列

Sql query distinct + other columns

例如,我有 sql table 条消息:

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 消息;它 returns

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?

您将要进行自连接:

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

您可以使用分析函数 rank,并在组内对其进行排序...

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 为 3 的消息是在 id 为 2 的消息之后创建的。通常,如果你有一个时间戳列,它会更合乎逻辑。在这种情况下,您可以使用 order by timestamp desc

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;