返回每组最大值为一列的行

Jer*_*emy 7 sql oracle max greatest-n-per-group

我很难在没有搜索同一个表至少两次以获取最大行的情况下执行此操作,然后获取该行的值.有问题的表格很大,所以这是不可接受的.

这是我的表可能是这样的:

SCORES
ID    ROUND    SCORE
1     1        3
1     2        6
1     3        2
2     1        10
2     2        12
3     1        6
Run Code Online (Sandbox Code Playgroud)

我需要返回每个ID在最近一轮中获得的分数.也就是说,行具有最大(圆形),但不是最大分数.

OUTPUT:
ID   ROUND   SCORE
1    3       2
2    2       12
3    1       6
Run Code Online (Sandbox Code Playgroud)

现在我有:

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;
Run Code Online (Sandbox Code Playgroud)

这是有效的,但效率很低(我必须手动过滤掉所有这些行,当我应该首先不能抓住那些行时.)

我能做些什么来获得正确的价值观?

Erw*_*ter 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;
Run Code Online (Sandbox Code Playgroud)

准确地返回您要求的内容.
关键点是窗口函数之后DISTINCT应用.

SQL小提琴.

也许更快,因为它使用相同的窗口两次:

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;
Run Code Online (Sandbox Code Playgroud)

否则做同样的事情.


Jus*_*ave 5

您使用分析函数走在正确的轨道上。但是你可能想要这样的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
Run Code Online (Sandbox Code Playgroud)

如果可能存在联系(具有相同id和的行round),您可能希望使用row_number分析函数而不是rank- 它将任意选择两个绑定行之一使其 arnk为 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
Run Code Online (Sandbox Code Playgroud)