我很难在没有搜索同一个表至少两次以获取最大行的情况下执行此操作,然后获取该行的值。有问题的表格很大,所以这是不可接受的。
这是我的表格的样子:
SCORES
ID ROUND SCORE
1 1 3
1 2 6
1 3 2
2 1 10
2 2 12
3 1 6
我需要返回每个ID在最近一轮中获得的分数。也就是说,行具有最大(圆形),但不是最大分数。
OUTPUT:
ID ROUND SCORE
1 3 2
2 2 12
3 1 6
现在我有:
SELECT * FROM
(SELECT id, round,
CASE WHEN (MAX(round) OVER (PARTITION BY id)) = round THEN score ELSE NULL END score
FROM
SCORES
where id in (1,2,3)
) scorevals
WHERE
scorevals.round is not null;
这有效,但效率很低(我必须手动过滤掉所有这些行,当我应该首先不能抓住那些行时。)
我能做些什么来获得正确的价值观?
答案 0 :(得分:7)
没有子查询也可以这样做:
SELECT DISTINCT
id
,max(round) OVER (PARTITION BY id) AS round
,first_value(score) OVER (PARTITION BY id ORDER BY round DESC) AS score
FROM SCORES
WHERE id IN (1,2,3)
ORDER BY id;
准确地返回您要求的内容
关键点是在窗口函数之后应用了DISTINCT
。
可能更快,因为它使用相同的窗口两次:
SELECT DISTINCT
id
,first_value(round) OVER (PARTITION BY id ORDER BY round DESC) AS round
,first_value(score) OVER (PARTITION BY id ORDER BY round DESC) AS score
FROM SCORES
WHERE id IN (1,2,3)
ORDER BY id;
否则也这样做。
答案 1 :(得分:4)
您使用分析功能走在正确的轨道上。但是你可能想要rank
函数
SELECT *
FROM (SELECT a.*,
rank() over (partition by id order by round desc) rnk
FROM scores
WHERE id IN (1,2,3))
WHERE rnk = 1
如果可以存在关联(具有相同id
和round
的行),您可能希望使用row_number
解析函数而不是rank
- 这将任意选择两个绑定行中的一个,使rnk
为{1},而不是将rank
作为MAX
返回。
如果您想使用SELECT *
FROM (SELECT a.*,
MAX(round) OVER (partition by id) max_round
FROM scores
WHERE id IN (1,2,3))
WHERE round = max_round
分析函数,您还可以执行类似
{{1}}
答案 2 :(得分:0)
对于这类问题,我倾向于使用max...keep...dense_rank
构造:
select
id,
max(round) round,
max(score) keep (dense_rank last order by round) score
from
tq84_scores
group by
id;