【问题标题】:ORACLE SQL find row with max date for each groupingORACLE SQL 查找每个分组的最大日期行
【发布时间】:2020-09-26 15:52:32
【问题描述】:

我正在尝试编写一个查询,它只返回行,每个 id 的时间值最大

Table: positions
id          time       otherCols...
---------- ----------- ----------
1           1     
1           2      
3           1      
1           3      
2           1       
3           2       

结果应如下所示:

id          time       otherCols...
---------- ----------- ----------      
1           3      
2           1       
3           2    

我尝试按 id 进行分组,但我不知道如何排序并只选择最高的结果。

【问题讨论】:

    标签: sql oracle group-by analytic-functions


    【解决方案1】:

    你可以使用MAX(..) KEEP (DENSE_RANK ..) OVER (PARTITION BY ..)解析函数而不需要任何子查询:

    SELECT MAX(time) KEEP (DENSE_RANK LAST ORDER BY time) 
                     OVER (PARTITION BY id) AS time_max,
           p.*
      FROM positions p
     ORDER BY id
    

    Demo

    【讨论】:

    • 为什么不直接使用GROUP BY?
    • OP 需要不确定数量的额外列。对于一两个,我会建议keep,但是对于一般查询,还有其他方法写起来不那么麻烦。
    • 是的,我只想过滤掉,列应该保持不变。
    • OK @boneash 我现在明白了,然后只需要添加其他列以及这个分析函数。
    【解决方案2】:

    你可以使用窗口函数:

    select t.*
    from (select t.*,
                 row_number() over (partition by id order by time desc) as seqnum
          from t
         ) t
    where seqnum = 1;
    

    另一种方法是相关子查询:

    select t.*
    from t
    where t.time = (select max(t2.time) from t t2 where t2.id = t.id);
    

    这与第一个查询在两个方面有所不同:

    • 如果id 有重复的时间,那么这将返回id 的所有 行。您可以在第一个查询中使用 rank() 获得该行为。
    • 这不会返回NULL id 值或ids,其中time 统一为NULL。第一个查询可以。

    【讨论】:

    • 感谢您的查询,看起来第二个要快得多,但它们给出的结果数量不同。
    • @boneash 。 . .这表明您对给定的id 有重复的时间。
    猜你喜欢
    • 2021-12-24
    • 2012-11-11
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多