[SQL_Q] 184. Department Highest Salary

Hyunjun Kim·2025년 7월 23일
0

SQL

목록 보기
59/90

https://leetcode.com/problems/department-highest-salary/

문제

Table: Employee

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| id           | int     |
| name         | varchar |
| salary       | int     |
| departmentId | int     |
+--------------+---------+
id is the primary key (column with unique values) for this table.
departmentId is a foreign key (reference columns) of the ID from the Department table.
Each row of this table indicates the ID, name, and salary of an employee. It also contains the ID of their department.
 

Table: Department

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
+-------------+---------+
id is the primary key (column with unique values) for this table. It is guaranteed that department name is not NULL.
Each row of this table indicates the ID of a department and its name.
 

Write a solution to find employees who have the highest salary in each of the departments.

Return the result table in any order.

The result format is in the following example.

 

Example 1:

Input: 
Employee table:
+----+-------+--------+--------------+
| id | name  | salary | departmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+
Department table:
+----+-------+
| id | name  |
+----+-------+
| 1  | IT    |
| 2  | Sales |
+----+-------+
Output: 
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Jim      | 90000  |
| Sales      | Henry    | 80000  |
| IT         | Max      | 90000  |
+------------+----------+--------+
Explanation: Max and Jim both have the highest salary in the IT department and Henry has the highest salary in the Sales department.

내 풀이

WITH first as (
SELECT departmentId, name, salary, 
rank() over(partition by departmentId order by salary DESC) as s_rank
FROM Employee
)
SELECT d.name as Department, f.name as Employee, salary as Salary
FROM first f join Department d
on f.departmentId = d.id
where f.s_rank = 1

장점

  • 가독성: 부서별로 순위를 매긴 뒤 RANK = 1만 뽑는 직관적인 방식
  • 확장성: RANK()를 쓰면 동점 처리(같은 급여)도 깔끔하게 됨
  • SQL 표준 문법: WINDOW FUNCTION을 지원하는 대부분의 DB에서 작동 가능

단점

  • RANK()는 윈도우 함수라서 Employee 테이블 전체에 대해 정렬과 파티셔닝 비용이 발생
  • 특히 데이터량이 많을 경우, 성능이 떨어질 수 있음

💡 성능 요약
O(N log N) 수준의 정렬 연산 발생 (부서별 정렬)
윈도우 함수는 인덱스를 잘 활용하지 못하는 경우가 많음


다른 사람 풀이

SELECT d.name AS Department, e.name AS Employee, e.salary
FROM Employee e
JOIN Department d ON e.departmentId = d.id
JOIN (
    SELECT departmentId AS d1, MAX(salary) AS s1
    FROM Employee 
    GROUP BY departmentId
) t1 ON e.departmentId = t1.d1 AND e.salary = t1.s1;

장점

  • GROUP BY + MAX()는 집계 연산이므로 인덱스를 잘 활용할 수 있음
  • Employee.salary에 인덱스가 있다면 성능 향상 가능
  • 윈도우 함수보다 훨씬 가볍고 빠름 (특히 데이터가 클 경우)

단점

  • 가독성 낮음: 부서별 최고 연봉을 먼저 찾고, 그 결과에 다시 JOIN으로 비교
  • GROUP BY 서브쿼리와 본 테이블을 다시 JOIN해야 하므로 중복 접근이 생김
  • 확장성이 떨어짐: 순위가 2등, 3등인 사람도 필요해지는 경우엔 구조 전체를 바꿔야 함

💡 성능 요약
서브쿼리는 O(N), JOIN은 일반적으로 O(N) 또는 O(log N) 수준
대용량에서 유리한 구조



성능 향상 패턴을 외우자: "집계 → JOIN으로 매핑"

단계SQL 동작설명
1GROUP BY + MAX어떤 기준으로 집계 (ex. 부서별 최대 급여)
2JOIN집계 결과를 원본 테이블에 연결해서 상세 정보 확보
3추가 JOIN필요한 보조 테이블(Department 등)을 추가


나의 쿼리 작성 방식은 다른 사람이 쓴 방식에 비해
가독성은 좋았지만 성능면에서 떨어진다.

사실 어떤 방식으로 쿼리를 작성해야 부하가 덜할지 고민은 하면서 쿼리를 작성했지만 다른 사람의 예시 쿼리를 보고 나니 별 차이가 없어 보여서 더 혼란스러워 졌다.

하지만 데이터 엔지니어를 목표로 하고 있다면
성능 개선에 대한 노력은 꾸준히 해줘야 한다고 생각한다.

쿼리 작성 시 나의 접근 방식을 다시 한 번 돌아보는 기회가 되었다.

profile
Data Analytics Engineer 가 되

0개의 댓글