How to get nᵗʰ highest value using plain SQL

前端 未结 8 1078
孤城傲影
孤城傲影 2021-01-24 23:42

What is the simplest way to get the nth highest value from a result set using plain SQL?

The result set would be huge, thus need to consider performance too.

8条回答
  •  说谎
    说谎 (楼主)
    2021-01-25 00:28

    This article talks about this question in depth, and I will quote code from it below:

    Solution 1: This SQL to find the Nth highest salary should work in SQL Server, MySQL, DB2, Oracle, Teradata, and almost any other RDBMS: (note: low performance because of subquery)

    SELECT * /*This is the outer query part */
    FROM Employee Emp1
    WHERE (N-1) = ( /* Subquery starts here */
    SELECT COUNT(DISTINCT(Emp2.Salary))
    FROM Employee Emp2
    WHERE Emp2.Salary > Emp1.Salary)
    

    The most important thing to understand in the query above is that the subquery is evaluated each and every time a row is processed by the outer query. In other words, the inner query can not be processed independently of the outer query since the inner query uses the Emp1 value as well.

    In order to find the Nth highest salary, we just find the salary that has exactly N-1 salaries greater than itself.


    Solution 2: Find the nth highest salary using the TOP keyword in SQL Server

    SELECT TOP 1 Salary
    FROM (
          SELECT DISTINCT TOP N Salary
          FROM Employee
          ORDER BY Salary DESC
          ) AS Emp
    ORDER BY Salary
    

    Solution 3: Find the nth highest salary in SQL Server without using TOP

    SELECT Salary FROM Employee 
    ORDER BY Salary DESC OFFSET N-1 ROW(S) 
    FETCH FIRST ROW ONLY
    

    Note that I haven’t personally tested the SQL above, and I believe that it will only work in SQL Server 2012 and up.


    Solution 4: Works in MySQL

    SELECT Salary FROM Employee 
    ORDER BY Salary DESC LIMIT n-1,1
    

    The LIMIT clause takes two arguments in that query – the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return.


    Solution 5: Works in Oracle

    select * from (
      select Emp.*, 
    row_number() over (order by Salary DESC) rownumb 
    from Employee Emp
    )
    where rownumb = n;  /*n is nth highest salary*/
    

    Solution 6: Works in Oracle way 2

    select * FROM (
    select EmployeeID, Salary
    ,rank() over (order by Salary DESC) ranking
    from Employee
    )
    WHERE ranking = N;
    

提交回复
热议问题