Can we find Nth Highest Salary in SQL
Loading
Can we find Nth Highest Salary in SQL
Know the answer? Post it — somebody with the same question will find it here.
Sign in to answer this question
It is the same account you read, post and publish with — and you will come straight back to this page.
Jaish MathewsPosted Feb 2, 2025, 7:04 AM
Its all scenario based.
Yes! You can find the Nth highest salary in SQL Server using several approaches. Here are the most common methods:
1. Using
DISTINCT+ORDER BY+OFFSET(SQL Server 2012+)
Nwith the desired rank.OFFSETto skip(N-1)rows and fetches theNthhighest salary.2. Using
TOP+DISTINCT+ORDER BY(Works in older SQL Server versions too)
(N-1)salaries and fetches the next highest salary.3. Using
DENSE_RANK()(Handles duplicate salaries properly)
DENSE_RANK()ensures that duplicate salaries don’t affect the ranking.4. Using
ROW_NUMBER()(Useful when there are no duplicate salaries)
Which One Should You Use?
DENSE_RANK().ROW_NUMBER()is fine.OFFSET FETCHis efficient.Let me know if you need help with any specific scenario! ??
Tuhin PaulPosted Feb 2, 2025, 10:35 AM
Part -2
Using Window Functions (
DENSE_RANK) (SQL Server/Oracle/PostgreSQL)Window functions like
DENSE_RANKallow you to rank rows without collapsing them into a single result.DENSE_RANK(), ordering by salary in descending order.N.Full Table Scan
The database reads all rows from the
Employeestable.Sorting
All salaries are sorted in descending order (
ORDER BY Salary DESC).Rank Assignment
DENSE_RANK()assigns a rank to each row. For example:Filtering
The outer query filters rows where
Rank = N.Why It's Inefficient for Large Datasets?
Full Sorting Overhead
Sorting the entire dataset has O(n log n) time complexity.
For a table with 1 million rows, this requires ~20 million operations.
No Short-Circuiting
Even if you only need the 10th highest salary, all rows are processed.
Example: For
N=10, the database still sorts 1M rows.Memory Pressure
Sorting and ranking large datasets consume significant memory.
May spill to disk if data exceeds available RAM.
Index Limitations
Most databases cannot use indexes to optimize window functions like
DENSE_RANK().Even with an index on
Salary, the full ranking process is still required.Redundant Work
If multiple users request different
Nvalues, the entire ranking process repeats each time.When to Use This Approach?
Small datasets (<10k rows).
When you need to handle tied salaries (e.g., two employees with the same salary at rank 2).
Ad-hoc queries where efficiency is not critical.
For large datasets, prefer indexed subqueries or lateral joins to avoid full sorting. For example:
This diagram is going to give you a deeper insights.
Tuhin PaulPosted Feb 2, 2025, 9:01 AM
Part -1
Using
LIMITandOFFSET(MySQL/PostgreSQL)This approach is straightforward and works well with databases that support
LIMITandOFFSET.Employeestable.LIMIT 1ensures that only one record is returned.OFFSET N-1skips the firstN-1records, effectively returning the Nth highest salary.For a dataset with 1 million records, using LIMIT and OFFSET can become inefficient because:
OFFSET 1000000), it results in high disk I/O and memory usage.Instead of using LIMIT and OFFSET, use a subquery with INDEX optimization:
1. Using a Subquery with DISTINCT and Index
Using a Self-Join (More Efficient for Top-N)
Why is this better?
Shubham SidnalePosted Feb 2, 2025, 7:51 AM
1. Using TOP with DISTINCT and ORDER BY (Subquery)
SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
OFFSET (N-1) ROWS FETCH NEXT 1 ROWS ONLY;
2. Using TOP with Subquery
SELECT TOP 1 Salary
FROM (SELECT DISTINCT TOP N Salary
FROM Employee
ORDER BY Salary DESC) AS Temp
ORDER BY Salary ASC;
3. Using DENSE_RANK() (Best for Handling Duplicates)
SELECT Salary
FROM (SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) AS rnk
FROM Employee) AS Ranked
WHERE rnk = N;
4. Using ROW_NUMBER() (When Duplicates Should Be Ignored)
SELECT Salary
FROM (SELECT Salary, ROW_NUMBER() OVER (ORDER BY Salary DESC) AS rnk
FROM Employee) AS Ranked
WHERE rnk = N;
5. Using CROSS APPLY (Efficient for Large Data)
SELECT Salary
FROM Employee E1
CROSS APPLY (SELECT COUNT(DISTINCT Salary) AS Rank
FROM Employee E2
WHERE E2.Salary >= E1.Salary) AS T
WHERE T.Rank = N;
6. Using OFFSET FETCH (Modern Approach)
SELECT Salary
FROM Employee
ORDER BY Salary DESC
OFFSET N-1 ROWS FETCH NEXT 1 ROW ONLY;
Choosing the Best Method:
Method
Handles Duplicates?
Performance
TOP with DISTINCT
Yes
Fast for small datasets
DENSE_RANK()
Yes
Best for handling duplicate salaries
ROW_NUMBER()
No
Best when uniqueness is required
CROSS APPLY
Yes
Good for large datasets
OFFSET FETCH
Yes
Modern approach, efficient
Which one to use depends on your requirements (handling duplicates) and SQL Server version.