ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [LeetCode Hard] 185. Department Top Three Salaries
    SQL 문제 풀이 2024. 1. 7. 11:39

    테이블 정보

     

    문제

    A company's executives are interested in seeing who earns the most money in each of the company's departments. A high earner in a department is an employee who has a salary in the top three unique salaries for that department.


    Write a solution to find the employees who are high earners in each of the departments.

    Return the result table in any order.

    The result format is in the following example.

     

     

    결과 예시

     

     

    정답 코드 (MySQL)

    WITH Salary_rank AS (
        SELECT id, name, salary, departmentId,
                DENSE_RANK() OVER(PARTITION BY departmentId ORDER BY salary DESC) AS salary_rank_by_department
        FROM Employee
    )
    
    SELECT d.name AS Department, 
            s.name AS Employee, 
            salary AS Salary
    FROM Salary_rank s
    JOIN Department d
    ON s.departmentId = d.id
    WHERE s.salary_rank_by_department <= 3;

     

     

    문제 풀이

    1. DENSE_RANK()

    우선 부서 별로 급여가 3위 안에 드는 사원들을 출력하면 되는 문제이다.

    문제 예시에서 볼 수 있다시피, 동점자인 IT 부서의 Joe와 Randy의 경우 2위로 동일 순위를 부여하고

    그 다음 순위인 Will을 3위로 부여하는 것을 볼 수 있다. 

     

    MySQL에는 순위를 반환하는 함수인 RANK()DENSE_RANK()가 존재한다.

    두 함수를 비교하기 위해,

    아래와 같이 사원 이름별 급여가 내림차순으로 정렬된 테이블이 존재한다고 생각해보자

     

    Name Salary
    Max 90000
    Joe 85000
    Randy 85000
    Will 70000
    Jung 50000

     

    RANK()

    • 동점자가 있을 때, 같은 순위를 부여하고 그 다음 순위는 해당 동점자 수를 고려하여 증가한다.
    • 예를 들어, 위와 같은 테이블에서는 RANK()를 적용했을 때 1등, 2등, 2등, 4등, 5등이 된다.

     

    DENSE_RANK()

    • 동점자가 있을 때, 같은 순위를 부여하고, 그 다음 순위를 연이어서 부여하는 기능이다.
    • 예를 들어, 위와 같은 테이블에서는 DENSE_RANK()를 적용했을 때 1등, 2등, 2등, 3등, 4등이 된다.

     

    WITH Salary_rank AS (
        SELECT id, name, salary, departmentId,
                DENSE_RANK() OVER(PARTITION BY departmentId ORDER BY salary DESC) AS salary_rank_by_department
        FROM Employee
    )

     

    departmentId를 기준으로 PARTITION BY를 적용한 상태에서, DENSE_RANK()를 적용해준 쿼리를

    가독성을 위해 WITH 절에 넣어주었다.

     

    2. JOIN

    departmentId가 Department 테이블의 id 컬럼을 참조하는 참조키이기 때문에,

    이를 기준으로 Department 테이블과 INNER JOIN을 수행해준다.

     

    즉, Salary_rank 서브쿼리 테이블의 별칭 "s"로 지정하고,

    Department 테이블을 "d"로 지정한 후에 s.departmentId와 d.id를 기준으로 조인해준다.

    이 때, WHERE 절에서 salary_rank_by_department 값이 3 이하인 행만 선택되게 조건을 추가해주면 된다.

     

    SELECT d.name AS Department, 
            s.name AS Employee, 
            salary AS Salary
    FROM Salary_rank s
    JOIN Department d
    ON s.departmentId = d.id
    WHERE s.salary_rank_by_department <= 3;
Designed by Tistory.