SQL interview questionsQuestion 6 of 14
SQL interview question · Question 6 of 14
Find the second-highest salary without using a simple MAX approach.
Short answer
Rank salaries with DENSE_RANK() ordered by salary descending, so tied salaries share a rank, then select the salary whose rank is 2. Exclude NULL salaries first, and wrap the result so the query returns NULL rather than no row when there is no second-highest value. The same pattern with PARTITION BY dept gives the second-highest per department.
On this page
Detailed explanation
Salaries: Ben 150, Chen 150, Asha 120, Fay 110, Dev 90, Eli NULL. The highest is 150 (shared by two people), so the second-highest distinct salary is 120.
WITH ranked AS (
SELECT salary,
DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employees
WHERE salary IS NOT NULL
)
SELECT DISTINCT salary FROM ranked WHERE rnk = 2; -- 120
DENSE_RANK gives 150 rank 1 for both Ben and Chen, then 120 rank 2.
Why not ROW_NUMBER?
ROW_NUMBER numbers rows 1, 2, 3 even when values tie, so row 2 is Chen’s 150, which is wrong. RANK would also be wrong: it gives 120 rank 3 because it skips a number after the tie.
Alternative: DISTINCT with OFFSET
SELECT DISTINCT salary
FROM employees
WHERE salary IS NOT NULL
ORDER BY salary DESC
LIMIT 1 OFFSET 1; -- 120
This is concise. Window functions generalise better (per department, Nth value, returning the employees too).
Return NULL when there is no second value
Some interview platforms expect NULL rather than an empty result. Wrap the query in a scalar subquery:
SELECT (SELECT DISTINCT salary FROM ranked WHERE rnk = 2) AS second_highest;
Per department, returning employees
WITH ranked AS (
SELECT dept, name, salary,
DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rnk
FROM employees
WHERE salary IS NOT NULL
)
SELECT dept, name, salary FROM ranked WHERE rnk = 2;
Common mistakes
- Using
ROW_NUMBERorRANKand getting the wrong value on ties. - Forgetting
NULLsalaries (they sort first or last depending on the engine). - Returning duplicate rows when several employees share the salary; add
DISTINCTif only the value is wanted.
Progress is saved in this browser only. No account needed.