我在留言簿中有一个包含用户评论的表格。列是:id,user_id,title,comment,timestamp。
我需要为每个用户选择最新的行。 我尝试使用group by但是没有管理它,因为我无法在同一个查询中选择其他任何我按user_id分组的内容:
SELECT user_id, MAX(ts) FROM comments GROUP BY user_id
例如在这个查询中我不能添加也选择列id,tilte和comment。怎么办呢?
答案 0 :(得分:6)
您可以使用JOIN
:
select c.*
from comments c join
(select user_id, max(ts) as maxts
from comments c2
group by user_id
) cc
on c.user_id = cc.user_id and c.ts = cc.maxts;
还有其他方法。典型的建议是使用row_number()
:
select t.*
from (select c.*, row_number() over (partition by user_id order by ts desc) as seqnum
from comments c
) c
where seqnum = 1;
这两个查询略有不同。如果用户的最新评论具有完全相同的ts
,则第一个将返回重复项。第二个为每个用户返回一行。
答案 1 :(得分:6)
您可以使用分析函数
SELECT *
FROM (SELECT c.*,
rank() over (partition by user_id order by ts desc) rnk
FROM comments c)
WHERE rnk = 1
根据您要处理关系的方式(如果有两行具有相同的user_id
和ts
),您可能需要使用row_number
或{{1} }而不是dense_rank
。如果存在平局,rank
将允许多行为第一行。如果存在平局,rank
会随意返回一行。对于首先绑定的行,row_number
的行为类似dense_rank
,但假设两行首先绑定,则将下一行视为第二行而不是第三行。
答案 2 :(得分:3)
使用dense rank first/last
函数
select id,
max(user_id) keep (dense_rank last order by ts) over (partition by id) as user_id,
max(title) keep (dense_rank last order by ts) over (partition by id) as title,
max(comment) keep (dense_rank last order by ts) over (partition by id) as comment,
max(ts) as ts
from comments;