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
장점
단점
💡 성능 요약
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;
장점
단점
💡 성능 요약
서브쿼리는 O(N), JOIN은 일반적으로 O(N) 또는 O(log N) 수준
대용량에서 유리한 구조
| 단계 | SQL 동작 | 설명 |
|---|---|---|
| 1 | GROUP BY + MAX | 어떤 기준으로 집계 (ex. 부서별 최대 급여) |
| 2 | JOIN | 집계 결과를 원본 테이블에 연결해서 상세 정보 확보 |
| 3 | 추가 JOIN | 필요한 보조 테이블(Department 등)을 추가 |
나의 쿼리 작성 방식은 다른 사람이 쓴 방식에 비해
가독성은 좋았지만 성능면에서 떨어진다.
사실 어떤 방식으로 쿼리를 작성해야 부하가 덜할지 고민은 하면서 쿼리를 작성했지만 다른 사람의 예시 쿼리를 보고 나니 별 차이가 없어 보여서 더 혼란스러워 졌다.
하지만 데이터 엔지니어를 목표로 하고 있다면
성능 개선에 대한 노력은 꾸준히 해줘야 한다고 생각한다.
쿼리 작성 시 나의 접근 방식을 다시 한 번 돌아보는 기회가 되었다.