【问题标题】:Suggest an efficient way to query建议一种有效的查询方式
【发布时间】:2013-02-22 04:56:08
【问题描述】:

给定一个表[a, b, c, d],我想在c 组中准确选择那些具有max(a) 的行

a = select max(a) from table group by c 的行

最有效的方法是什么?我可以使用分区子句等吗?

【问题讨论】:

    标签: sql oracle group-by


    【解决方案1】:

    在现实世界中,几乎任何时候都存在可以推测对您有利的线索,问题的特殊性。

    您的问题虽然是理想情况,但没有特殊性。此查询将全盘扫描表,然后将进行一些排序以找到最大 a:

    select a,b,c,d
    from(
        select 
          a,
          b,
          c,
          d, 
          row_number() over (partition by c order by a desc) as rnk_in_group_of_c
        from table
    )
    where rnk_in_group_of_c = 1;
    

    此查询比使用子查询查找最大值要好,因为它可能会导致多次完整扫描、不需要的嵌套循环或其他性能问题。

    请注意,如果您想要所有具有最大 a 的行(即有两个相等的最大行),您应该使用 dense_rank() 函数而不是 row_number()

    【讨论】:

      【解决方案2】:

      您是否尝试过keep (dense_rank first 这对我有很大帮助,并且性能会好很多。

      select 
         max(a) a,
         max(b) keep (dense_rank first order by a desc) b,
         c,
         max(d) keep (dense_rank first order by a desc) d
      from table
      group by c
      

      【讨论】:

      • 性能不一定是最好的,正如Rob van Wijk 解释得很好,但如果列数较少,它可能会快很多。
      • @Ben - 作为一个业余爱好者,我只做过一次并且效果很好,从我过去的问题可以看出。我正在学习中感谢您的回复! :)
      • 我们都在学习 :-);或者至少我希望如此!阅读博文;这是为什么应该使用 KEEP 的一个很好的例子;在大量列上并不总是更快。如果速度不是问题,但 TEMP 空间是问题,那么它仍然是值得的,因为 SORT GROUP BY 减少了必须计算的行数。
      • @Ben-感谢您的Blog。只是这里发生的讨论!
      【解决方案3】:

      可以在分区后添加可选的order by:

       SELECT max(a) OVER (PARTITION BY c) max_c FROM...
      

      【讨论】:

        猜你喜欢
        • 2016-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-28
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多