【问题标题】:Select second most minimum value in Oracle在 Oracle 中选择第二个最小值
【发布时间】:2012-01-01 13:14:32
【问题描述】:

我需要编写一个查询,从整数列表中选择一个最小值并且它是第二个最小值。

取最小值很明显:

select min(value) from table;

但是第二小的就不那么明显了。

为了记录,这个整数列表不是连续的——最小值可以是 1000,第二大的最小值可以是 10000。

【问题讨论】:

    标签: sql oracle oracle11g greatest-n-per-group


    【解决方案1】:

    使用分析函数

    SELECT value
      FROM (SELECT value,
                   dense_rank() over (order by value asc) rnk
              FROM table)
     WHERE rnk = 2
    

    分析函数RANKDENSE_RANKROW_NUMBER 是相同的,只是它们处理平局的方式不同。 RANK 使用体育风格的打破平局的过程,因此如果两行并列排名为 1,则下一行的排名为 3。DENSE_RANK 给并列第一名的两行排名为 1,然后将下一行分配为 2。ROW_NUMBER 任意打破平局,将具有最低值的两行之一的排名为 1,另一行的排名为 2。

    【讨论】:

    • +1 与我发布的解决方案相同,但对三个类似分析函数之间的区别进行了很好的附加说明。
    • 分析函数!为什么我以前没有想到他们。感谢您的帮助和解释。
    【解决方案2】:
    select 
      value
    from
      (select 
        value, 
        dense_rank() over (order by value) rank
      from 
        table)
    where
      rank = 2
    

    优点:您可以很容易地获得第三个值,或者底部 10 行(排名

    请注意,此查询的性能将受益于 'value' 上的正确索引。

    【讨论】:

      【解决方案3】:
      SELECT MIN(value)
      FROM TABLE
      WHERE Value > (SELECT MIN(value) FROM TABLE)
      

      【讨论】:

      • 请注意,这需要两次敲表,因此它会比解析函数解决方案更昂贵。如前所述,当您想要第 3 行、第 5 行或第 10 行时,也很难扩展。您可以对表中的行数进行 COUNT(*),这些行的值小于外部查询中的当前行,这更容易扩展但效率要低得多。
      • 我赞成您的解决方案,因为它很聪明,但我不会使用它。
      猜你喜欢
      • 2021-07-23
      • 2017-01-10
      • 1970-01-01
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 1970-01-01
      相关资源
      最近更新 更多