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;
例如,我有 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;