use*_*094 4 sql postgresql greatest-n-per-group
我有下表(scores):
id user date score
---|-----|------------|--------
1 | 10 | 11/01/2016 | 400
2 | 10 | 11/03/2016 | 450
5 | 17 | 10/03/2016 | 305
3 | 13 | 09/03/2016 | 120
4 | 17 | 11/03/2016 | 300
6 | 13 | 08/03/2016 | 120
7 | 13 | 11/12/2016 | 120
8 | 13 | 09/01/2016 | 110
Run Code Online (Sandbox Code Playgroud)
我想max(score)为每个不同的用户进行选择,用作date决胜局(在平局的情况下,应返回最近的记录),以便结果如下所示(每个用户的最高分,按score降序排序命令):
id user date score
---|-----|------------|--------
2 | 10 | 11/03/2016 | 450
5 | 17 | 10/03/2016 | 305
7 | 13 | 11/12/2016 | 120
Run Code Online (Sandbox Code Playgroud)
我正在使用 Postgres,但无论如何我都不是 SQL 专家。我尝试过类似于以下内容的方法,但它不起作用,因为我没有id在以下内容中包含该列group by:
select scores.user, max(scores.score) as score, scores.id
from scores
group by scores.user
order by score desc
Run Code Online (Sandbox Code Playgroud)
我有一种感觉,我需要进行子选择,但我无法让连接正常工作。我发现How can I SELECT rows with MAX(Column value), DISTINCT by another columns in SQL? 但我似乎无法使任何解决方案对我有用,因为我需要返回行id,并且列上可能存在平局date。
小智 5
在 Postgres 中,最快的方法通常是使用distinct on ()
select distinct on (user_id) *
from the_table
order by user_id, score desc;
Run Code Online (Sandbox Code Playgroud)
这肯定比使用子查询的任何解决方案快得多,并且通常max()仍然比使用窗口函数的等效解决方案快一点(例如row_number())
我使用user_id列名是因为user它是保留字,我强烈建议不要使用它。