查询中的多个最大值

kur*_*ast 6 sql oracle greatest-n-per-group

我知道标题听起来不是很具描述性,但它是我能想到的最好的:

我有这张桌子

ID     BDATE      VALUE
28911  14/4/2009  44820
28911  17/4/2009  32240
28911  20/4/2009  30550
28911  22/4/2009  4422587,5
28911  23/4/2009  4441659
28911  24/4/2009  7749594,67
38537  17/4/2009  58280
38537  20/4/2009  137240
38537  22/4/2009  81098692
38605  14/4/2009  2722368
38605  20/4/2009  5600
38605  22/4/2009  1625400
38605  23/4/2009  6936575

这实际上是一个封装在视图中的非常复杂的查询,但现在不是问题.

我想为每个ID,包含最高BDate的行.在这个例子中,这将是结果.

ID     BDATE      VALUE
28911  24/4/2009  7749594,67
38537  22/4/2009  81098692
38605  23/4/2009  6936575

我已经尝试过了

select id, max(bdate), value from myview group by id, value
Run Code Online (Sandbox Code Playgroud)

但随后它返回所有行,因为每个行的值不同.此查询是在Oracle v10中设计的,我有资格仅使用选择查询而不是创建过程.

APC*_*APC 12

select id, bdate, value 
from myview 
where (id, bdate) in
    (select id, max(bdate)
     from myview group by id)
/
Run Code Online (Sandbox Code Playgroud)


Vin*_*rat 12

你可以使用MAX...KEEP(DENSE_RANK FIRST...)构造:

SQL> SELECT ID,
  2         MAX(bdate) bdate,
  3         MAX(VALUE) KEEP(DENSE_RANK FIRST ORDER BY bdate DESC) VALUE 
  4   FROM DATA
  5  GROUP BY ID;

        ID BDATE            VALUE
---------- ----------- ----------
     28911 24/04/2009  7749594,67
     38537 22/04/2009    81098692
     38605 23/04/2009     6936575
Run Code Online (Sandbox Code Playgroud)

这将与Majkel建议的分析方法一样高效(没有自联接,单次传递数据)


And*_*mar 5

您可以使用 INNER JOIN 仅过滤掉最大行数:

select t.*
from YourTable t
inner join (
     select id, max(bdate) as maxbdate
     from YourTable
     group by id
) filter
    on t.id = filter.id
    and t.bdate = filter.maxbdate
Run Code Online (Sandbox Code Playgroud)

这打印:

id     bdate       value
38605  2009-04-23  6936575
38537  2009-04-22  81098692
28911  2009-04-24  7749594.67
Run Code Online (Sandbox Code Playgroud)

请注意,这将返回一个 id 的多行,该 id 具有多个具有相同 bdate 的值。