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.
In a general database, you can do this with a subquery and two order by
s. The problem is that top/limit/rownum syntax is not standard. In some databases you would write:
Sub Query will list out top 'n' highest salary values. From that list minimum value will be the nth highest salary.
`SELECT min(salary) FROM
(SELECT DISTINCT TOP n salary FROM EmployeeTable ORDER BY salary desc);`
Eg :- SQL query to find third maximum salary
`SELECT min(salary) FROM
(SELECT DISTINCT TOP 3 salary FROM EmployeeTable ORDER BY salary desc);`
Start by producing an ordered, numbered dataset and then select from that. The precise syntax depends on the RDBMS but, for example, in Oracle you can do
SELECT ROWNUM, SOMEVAL
FROM (SELECT SOMEVAL FROM SOMETABLE ORDER BY SOMEVAL DESC)
Given the above set you can
SELECT SOMEVAL WHERE ROWNUM = :N
In Oracle:
SELECT * FROM (
SELECT col1, ROW_NUMBER()OVER(ORDER BY col1) rnum_col1 FROM table1
) WHERE rnum_col1 = 10;
Let's say you want to find the 5th highest salary, you first take the first 5 distinct salary order by descending order so that the last one is the 5th highest salary (See inner query). You then reorder it in ascending order and take the first.
SELECT TOP 1 Salary FROM
(
SELECT DISTINCT TOP 5 Salary
FROM Employee
ORDER BY Salary DESC) t
ORDER BY Salary ASC
You have to incur the overhead of sorting, and in my example rownum
is the sorted row number, not the physical location.
Since everyone is using analytic functions to show how this works here is one:
select foo,bar, max(baz)
from
(
select *
from
(
select foo,bar,baz, row_number() over
(partition by some_identifier_that_Groups order by value DESC) rn
)
where rn = 1 -- get the highest value for each partition
) group by foo,bar