본문 바로가기
Data Science/SQL

[SQL/오답] 부하 직원이 5명 이상인 매니저 찾기: 셀프 조인과 서브쿼리의 활용 (LeetCode570 Medium)

by 에르모사 쩐뉴 2026. 2. 6.

570. Managers with at Least 5 Direct Reports; INNER JOIN, SUBQUERY

1. Problem

한 테이블 안에 직원과 매니저 정보가 섞여 있는 구조에서, 직속 부하가 5명 이상인 매니저의 이름을 찾아야 한다.

  • 핵심 과제: managerId 컬럼을 통해 누가 누구를 관리하는지 파악하고, 특정 id가 managerId 열에 5번 이상 등장하는지 체크하여 그 id에 해당하는 name을 매칭하는 것이다.

2. Solution: 두 가지 객관적 접근법

① 서브쿼리(IN)를 이용한 방식 (직관적) 먼저 조건을 만족하는 'ID 리스트'를 뽑고, 그 리스트에 포함된 이름을 메인 쿼리에서 가져온다.

② INNER JOIN을 이용한 방식 (데이터 정합성) 매니저 테이블(m)과 부하 직원 테이블(e)을 가상으로 나누어 조인한다.

3. Takeaway: 왜 GROUP BY managerId 후 name을 바로 쓸 수 없는가? (객관적 분석)

  • 비집계 컬럼의 모호성 (유진 님의 오답 분석):
    • 오답: SELECT name FROM Employee GROUP BY managerId HAVING Count(*) >= 5
    • 원인: GROUP BY managerId를 하면 엔진은 '매니저 ID'를 기준으로 행들을 묶는다. 하지만 SELECT 절에서 요구하는 name은 해당 그룹 안에 여러 명이 섞여 있을 수 있다(물론 논리적으로 한 매니저 ID는 하나의 이름을 갖겠지만, SQL 엔진 입장에서는 '어떤 행의 이름을 보여줘야 할지' 확신할 수 없다).
    • 해결: 따라서 서브쿼리로 ID를 먼저 확정 짓거나, 조인을 통해 매니저의 id와 name을 함께 그룹화(GROUP BY m.id, m.name)해야 한다.

Table: Employee

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
| department  | varchar |
| managerId   | int     |
+-------------+---------+
id is the primary key (column with unique values) for this table.
Each row of this table indicates the name of an employee, their department, and the id of their manager.
If managerId is null, then the employee does not have a manager.
No employee will be the manager of themself.
 

Write a solution to find managers with at least five direct reports.

Return the result table in any order.

The result format is in the following example.

 

Example 1:

Input: 
Employee table:
+-----+-------+------------+-----------+
| id  | name  | department | managerId |
+-----+-------+------------+-----------+
| 101 | John  | A          | null      |
| 102 | Dan   | A          | 101       |
| 103 | James | A          | 101       |
| 104 | Amy   | A          | 101       |
| 105 | Anne  | A          | 101       |
| 106 | Ron   | B          | 101       |
+-----+-------+------------+-----------+
Output: 
+------+
| name |
+------+
| John |
+------+

 

# 정답 코드
# 서브쿼리를 이용한 풀이

SELECT name 
FROM Employee
WHERE id IN (
    SELECT managerId           # 5명 이상의 부하를 거느린 매니저들의 id만 먼저 골라낸다.  
    FROM Employee
    GROUP BY managerId
    HAVING Count(*) >= 5);
# 또 다른 정답 코드
# INNER JOIN을 이용한 풀이

SELECT m.name
FROM Employee m
JOIN Employee e ON m.id = e.managerId
GROUP BY m.id, m.name
HAVING COUNT(e.id) >= 5;

 

INNER JOIN한 결과

m.id (Manager) m.name e.id (Report) e.name
101 john 102 dan
101 john 103 james
101 john 104 amy
101 john 105 anne
101 john 106 ron

 

# 오답 코드

SELECT name   #그룹화되지 않은 컬럼을 마음대로 꺼내 쓸 수 없음!!! 어떤 매니저 이름을 줘야하지?
FROM Employee
GROUP BY managerId
HAVING Count(*) >= 5;