✏️ Explanatory Question

Find the 2nd highest salary per department, handling ties correctly

👁 11 Views
📘 Detailed Answer
🟢 Easy
💡

Answer with Explanation

Section 13: Complex Query Writing Challenges

93

Find the 2nd highest salary per department, handling ties correctly

Level: Hard — A whiteboard classic; the "per group" and "ties" twists trip up most candidates.

Scenario: HR wants the second-highest-paid employee in each department for a bonus program. The interviewer adds two twists: (1) it must be per department, not overall, and (2) ties must be handled correctly — if two people share the top salary, who is "second"?

Sample Data — employees

emp_idnamedept_idsalary
1Rumman1090000
2Krushna1090000
3Swetha1075000
4Ritesh1060000
5Manjula2080000
6Elitam2050000
The critical ambiguity: In dept 10, two people earn 90,000 (tied for #1). Is the "2nd highest" salary 75,000 (the next distinct value) or 90,000 (the second person)? This choice determines whether you use DENSE_RANK or ROW_NUMBER — clarify it with the interviewer!

The Three Ranking Functions Give Different Answers

salaryROW_NUMBERRANKDENSE_RANK
90000111
90000211
75000332
60000443

"2nd highest" = the second person → ROW_NUMBER = 2 (Krushna, 90000). "2nd highest distinct salary" → DENSE_RANK = 2 (Swetha, 75000).

Solution A — 2nd Highest DISTINCT Salary (DENSE_RANK)

-- "Second-highest distinct salary value" per department
SELECT dept_id, name, salary
FROM (
    SELECT dept_id, name, salary,
           DENSE_RANK() OVER (
               PARTITION BY dept_id
               ORDER BY salary DESC
           ) AS drnk
    FROM employees
) t
WHERE drnk = 2;
-- Dept 10 -> Swetha 75000  |  Dept 20 -> Elitam 50000

Solution B — The 2nd Person (ROW_NUMBER)

-- "Second-highest-PAID employee" (each person ranked uniquely)
SELECT dept_id, name, salary
FROM (
    SELECT dept_id, name, salary,
           ROW_NUMBER() OVER (
               PARTITION BY dept_id
               ORDER BY salary DESC, emp_id  -- tie-break for determinism
           ) AS rn
    FROM employees
) t
WHERE rn = 2;
-- Dept 10 -> Krushna 90000  |  Dept 20 -> Elitam 50000

Solution C — Without Window Functions (older MySQL 5.7)

-- Correlated subquery approach for "2nd highest distinct salary"
SELECT e.dept_id, e.name, e.salary
FROM employees e
WHERE (
    SELECT COUNT(DISTINCT e2.salary)
    FROM employees e2
    WHERE e2.dept_id = e.dept_id
      AND e2.salary > e.salary
) = 1;   -- exactly one distinct salary is higher -> it's the 2nd highest
The senior move: Before writing any SQL, ask the interviewer to define "2nd highest" when ties exist. Demonstrating that you spotted the ambiguity is often worth more than the query itself.
Interviewer follow-up: "Now give me the Nth highest, and handle departments that don't have N distinct salaries." → Parameterize WHERE drnk = N. Departments with fewer than N distinct salaries simply return no row — mention you'd LEFT JOIN back to departments if you must show every department even when there's no Nth value.