mysql 문제풀이/easy

Leetcode 185 - Department Top Three Salaries

gooreumsea 2023. 9. 20. 02:53

https://leetcode.com/problems/department-top-three-salaries/

 

습득한 점:

윈도우 함수를 활용할 때,
DENSE_RANK() OVER (PARTITION BY departmentid ORDER BY salary DESC)
 
처럼 PARTITION BYORDER BY를 함께 쓸 수 있다는 점을 알게되었음.
 
 
 
+ 순위 정하기 함수의 차이점 - ROW_NUMBER(),  RANK(),  DENSE_RANK()
 
SELECT val
     , ROW_NUMBER() OVER (ORDER BY val) AS row_number
     , RANK() OVER (ORDER BY val) AS rank
     , DENSE_RANK() OVER (ORDER BY val) AS dense_rank
FROM Sample;

 

- row_number는 어떻게 해서든 123456 으로 순위 매김 (중복포함)

 

- rank는 동일 값에 같은 등수를 부여, 공동 등수의 갯수를 고려한, 다음 순위를 매김.
 
아래 예시의 경우에는 2등과 5등은 스킵한 뒤 순위를 매김

 

- dense_rank는 공동 등수를 하나로 보고 다음 순위를 매김

VALUE ROW_NUMBER() RANK() DENSE_RANK()
1 1 1 1
1 2 1 1
2 3 3 2
3 4 4 3
3 5 4 3
4 6 6 4

 

 

 

문제:

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.

 

요약: # 각 부서에서 직원들의 급여 순으로, 부서별 1위 2위 3위 찾기 (급여가 같은 사람이 2명이상이라면 모두 포함시키기)

 

 

 

문제파악:

1. Foreign key가 id 이므로 Employee와 Department의 id로 테이블 조인
 
2. 급여가 같은 직원들의 경우에도 모두 찾아내야 하므로 dense_rank 활용
 
3. 파트별로 순위 매기기 위해서 PARTITION BY ~ 활용
 
4. WHERE 조건 활용하기 위해선, 테이블 자체를 새로 생성해야 함.

 

 

 

풀이:

난이도가 hard 이지만 어렵진 않았다.

전체적인 틀은 같지만,

FROM 절에 넣어도 되고 WITH 절에 넣어도 괜찮을 것 같다.

 

1) WITH절 활용

WITH COUNTER AS (
      SELECT Dep.name DepName
          , Emp.name EmpName
          , salary
          , DENSE_RANK() OVER (PARTITION BY departmentid ORDER BY salary DESC) AS denserank
      FROM Employee AS Emp
          INNER JOIN Department AS Dep ON Dep.id = Emp.departmentId
                 )

SELECT DepName AS Department
     , EmpName AS Employee
     , salary
FROM COUNTER
WHERE denserank <=3

 

 

2) FROM절 서브쿼리 활용

SELECT t.department
     , t.employee
     , t.salary
     
FROM(
    SELECT department.name AS dapartment
        , employee.name AS employee
        , employee.salary
        , DENSE_RANK() OVER (PARTITION BY departmentid ORDER BY salary DESC) AS dr

    FROM Employee
        INNER JOIN dapartment ON employee.departmentId = dapartment.id
    ) t
WHERE t.dr <=3