【问题标题】:Select second largest from a table without limit从无限制的表中选择第二大
【发布时间】:2010-10-19 10:01:18
【问题描述】:

我们如何在不使用 LIMIT 的情况下从表格中选择第二大标记或其他标记? 我知道可以使用 LIMIT,但不使用它是否可以?

假设我们有列id 和marks。

【问题讨论】:

  • 你不喜欢 LIMIT 的哪一点?
  • 那是一个面试问题;)
  • 我认为问题可能是在不使用 ORDER BY 和 LIMIT 的情况下解决它。因为 order by 要求在 O(n*log(n)) 中排序,而面试官正在寻找 O(n)

标签: mysql sql select


【解决方案1】:

假设标记是唯一的,下面的查询会给你第二大标记。

SELECT   MAX(marks)
FROM     ATable
WHERE    marks < (SELECT MAX(marks) FROM ATable)

要获取整个记录,您可以将其包装在 INNER JOIN

SELECT  t1.*
FROM    ATable t1
        INNER JOIN (
          SELECT   marks = MAX(marks)
          FROM     ATable
          WHERE    marks < (SELECT MAX(marks) FROM ATable)
        ) t2 ON t2. marks = t1.marks

【讨论】:

  • 对于MySql:select * from atable where tags = (select max(marks) as secmax from atable where tags
  • 是 '(SELECT MAX(marks) FROM ATable)' 被兑现还是对每一行都运行此查询?因为这种方法在大约 1000 行的表上非常慢,谢谢
  • @Gabriel - 请注意,查询只返回一行。在正确的索引表上,这会导致一次索引扫描和一次索引查找。对于任何称职的数据库引擎来说,这都不是问题。
  • 感谢回复,我明白了,很遗憾,我的查询没那么简单,查询返回的不止一行。就像 WHERE foo NOT IN (SELECT MAX(bar) FROM Table group by baz)
【解决方案2】:
select max(number), id 
from <tableName>
where number < (select max(number) from <tableName>)

【讨论】:

    【解决方案3】:

    你可以做一个

    SELECT MAX(marks) FROM TABLE 
    WHERE marks NOT IN (SELECT MAX(marks) FROM TABLE)
    

    但是 LIMIT 应该比上面的表现更好,所以问题是你为什么不喜欢它?

    【讨论】:

      【解决方案4】:

      如果您需要整行(所有列),这个就可以了。此外,它总是只返回一行,即使有多个具有相同的第二个最大值。

      Select top 1 * 
        From (Select Top 2 * 
                From TABLE 
               Order By marks desc
             ) a
      Order By marks asc
      

      如果你只想要一行具有真正的第二个最大值,你应该使用:

      select Top 1 * 
        from TABLE
       where marks < (select max(marks) from TABLE)
      Order by max desc
      

      也可以通过 CTE (SQL Server 2005+) 完成:

      ;With a as 
      (
      Select Dense_Rank() over (order by marks desc) as nRank,
             *
        From TABLE
      )
      Select Top 1 * 
        from a
       Where nRank=2
      

      如果您想查看所有具有第二个最大标记的行,只需从上一个查询中删除 TOP 1。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-05
        • 2013-07-16
        • 2020-01-08
        • 1970-01-01
        • 2013-07-30
        • 1970-01-01
        相关资源
        最近更新 更多