185. Department Top Three Salaries

각 부서에서 누가 가장 많은 급여를 받는지 알고 싶어! 이를 위해 각 부서의 "High Earner" 타이틀을 부여할 것이며, 이 타이틀은 부서별로 급여 기준 상위 3명에게 주어진다. 같은 급여를 받는 여러 명이 있을 수도 있기 때문에 순위는 급여 중심으로 평가한다.
한마디로, 급여별 순위를 부여한 다음 1위~3위까지의 당사자를 알아내는 문제다.
중요한 것은 중복값을 허용한다는 것이다. 만약 10달러, 9달러, 9달러, 8달러 순서로 정렬이 된다면 1위~3위는 총 4명이 되는 것이다.
JOIN을 사용해 Employee와 Department 테이블을 통합하여 필요한 데이터를 포함한 테이블을 만든다.RANK() 또는 DENSE_RANK() 윈도우 함수를 사용한다.WITH cleaned AS (
SELECT
d.name AS Department,
e.name AS Employee,
e.salary AS Salary
FROM Employee e
JOIN Department d ON e.departmentId = d.id
)
SELECT
Department,
Employee,
Salary
FROM
(
SELECT
*,
RANK() OVER (PARTITION BY Department ORDER BY Salary) AS ranked
FROM cleaned
ORDER BY Department
) ranking
WHERE ranked < 4;
RANK() 사용 시 동일한 급여를 가진 사람들에게 동일한 순위가 부여되며, 다음 순위는 건너뛰게 된다. 즉, 1, 2, 2 다음에 4가 오게 된다. 이는 정확한 결과를 방해할 수 있다.ORDER BY 절에서 DESC를 명시해주어야 한다.WITH sub AS (
SELECT
d.name AS Department,
e.name AS Employee,
e.salary AS Salary,
DENSE_RANK() OVER (PARTITION BY d.name ORDER BY e.salary DESC) AS ranked
FROM Employee e
JOIN Department d ON e.departmentId = d.id
)
SELECT Department, Employee, Salary
FROM sub
WHERE ranked <= 3;
DENSE_RANK() 함수는 동일한 값에 동일한 순위를 부여하고 다음 순위를 건너뛰지 않기 때문에 RANK()보다 적합하다. 예를 들어, 1, 2, 2 다음에 3이 오게 된다.ORDER BY e.salary DESC: DESC를 사용하여 내림차순으로 정렬함으로써 높은 급여가 먼저 평가된다.RANK(), DENSE_RANK(), ROW_NUMBER()의 차이를 명확히 이해하고, 상황에 맞는 윈도우 함수를 선택하는 것이 중요하다.ORDER BY의 정렬 기준(오름차순, 내림차순)을 명확히 정의해야 원하는 결과를 얻을 수 있다.이 TIL을 통해 SQL 윈도우 함수를 이용해 데이터를 그룹별로 순위 매기는 방법과 실수하기 쉬운 부분들을 다시 한번 짚어보게 되었다. 👏