How to get nᵗʰ highest value using plain SQL

前端 未结 8 1075
孤城傲影
孤城傲影 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:25

    This is the T-SQL (SQL-Server 2005 and greater) approach using ROW_NUMBER:

    WITH CTE AS
    (
       SELECT 
          Col1, Col2, ValueCol,
          RN = ROW_NUMBER() OVER (ORDER BY ValueCol DESC) -- change to ASC if you want lowest first
       FROM 
          dbo.TableName
    )
    SELECT 
       Col1, Col2, ValueCol
    FROM 
       CTE
    WHERE 
       RN = @nthhighestvalue
    

    If you want all rows with the same value use DENSE RANK instead.

    Difference between ROW_NUMBER, RANK and DENSE_RANK

    0 讨论(0)
  • 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;
    
    0 讨论(0)
提交回复
热议问题