假设我有一个这样结构的表格
姓名 | 分数 |
---|---|
迈克 | 40 |
迈克 | 79 |
迈克 | 49 |
我只想返回迈克得分为 79 的行,而不返回其他内容。
我一直在使用的代码如下所示:
SELECT Name, COUNT(Name), greatest(Score) FROM
table GROUP BY Name, Score
我尝试了一些不同的变体,例如使用 Rank 和最伟大的函数,但运气不佳。任何帮助将不胜感激,谢谢。
不确定为什么其他答案使事情变得复杂,你只是想使用 max 函数,如下所示:
WITH data(name, score) as (
select * from values
('Mike', 40),
('Mike', 79),
('Mike', 79)
)
select name, max(score) as score
from data
where name ='Mike' group by name;
您的询问:
SELECT Name, COUNT(*), max(Score) FROM
table GROUP BY Name
从功能角度来看, greatest
与 max “类似”,但正如您所提到的,它不起作用,这是因为它的签名 - 它并不意味着接收单个 expr 作为输入。我建议您阅读最大和最大之间的差异,以确保您完全理解它们。
使用 QUALIFY 和 RANK/ROW_NUMBER:
SELECT *
FROM tab
QUALIFY RANK() OVER(PARTITION BY Name ORDER BY Score DESC) = 1
详细解释:
如果您向更改后的数据添加 ROW_NUMBER 和 RANK:
WITH data(name, score, extra) as (
select * from values
('Mike', 40, 'a'),
('Mike', 79, 'b'),
('Mike', 79, 'c')
)
select *
,row_number() over (partition by name order by score desc) as rn
,rank() over (partition by name order by score desc) as rank
from data;
姓名 | 得分 | 额外 | RN | 排名 |
---|---|---|---|---|
迈克 | 79 | b | 1 | 1 |
迈克 | 79 | c | 2 | 1 |
迈克 | 40 | a | 3 | 3 |
您可以看到 ROW_NUMBER 只会将值 1 分配给一个值,其中 RANK 将为您提供保留该位置的尽可能多的值,并且在稀疏 RANK 的情况下会有间隙,因为
Mike,40
是第三个值。因此,RANK/ROW_NUMBER 之间的选择取决于您想要如何处理结果以及您是否要加入此数据等。
然后你可以用经典的 ANSI 形式进行过滤:
WITH data(name, score, extra) as (
select * from values
('Mike', 40, 'a'),
('Mike', 79, 'b'),
('Mike', 79, 'c')
)
select name, score, extra
from (
select *
,row_number() over (partition by name order by score desc) as rn
from data
)
where rn = 1;
请注意,这是一种不稳定的排序,因为数据库可以返回 Mike,79,b 或 Mike,79,c,但使用 ROW_NUMBER 您只会得到一个。
Snowflake 具有 QUALIFY 命令,允许删除子选择,并在分组完成后运行另一个过滤器。
所以你可以写:
select *
,row_number() over (partition by name order by score desc) as rn
from data
QUALIFY rn = 1;
姓名 | 得分 | 额外 | RN |
---|---|---|---|
迈克 | 79 | b | 1 |
但是如果您不想看到 ROW_NUMBER 值,可以将其移至 QUALIFY,并且范围时间与查询完全相同,但这使事情变得更整洁:
WITH data(name, score, extra) as (
select * from values
('Mike', 40, 'a'),
('Mike', 79, 'b'),
('Mike', 79, 'c')
)
select *
from data
QUALIFY row_number() over (partition by name order by score desc) = 1;
姓名 | 得分 | 额外 |
---|---|---|
迈克 | 79 | b |
MAX_BY 可能就是您所需要的https://docs.snowflake.com/en/sql-reference/functions/max_by