직원 네 명의 이름과 상사를 함께 조회했는데 결과는 세 명이다. 사라진 사람은 상사가 없는 대표 Mira. 직원 명부를 뽑는 쿼리에서 대표를 퇴사시킨 셈이지만, 데이터는 그대로다. 같은 테이블을 조인하는 방식과 어떤 쪽 행을 남길지가 문제다.
직원과 상사를 같은 테이블에서 어떻게 연결할까?
직원은 staff 테이블에 한 번만 저장한다. manager_id에는 상사 직원의 id를 넣는다. 아래 네 명에서 Mira는 상사가 없고, Jin·Sol의 상사는 Mira, Hana의 상사는 Jin이다.
CREATE TABLE staff (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
manager_id INTEGER REFERENCES staff(id)
);
INSERT INTO staff (id, name, manager_id) VALUES
(1, 'Mira', NULL),
(2, 'Jin', 1),
(3, 'Sol', 1),
(4, 'Hana', 2);manager_id가 가리키는 것도 같은 staff다. 그래서 이 테이블을 직원 역할 e와 상사 역할 m으로 두 번 지정해 e.manager_id = m.id로 연결한다. 데이터가 두 벌 복제되는 것은 아니다. 별칭은 한 테이블을 두 역할로 구별하기 위한 이름이다.
INNER JOIN에서 상사가 없는 Mira는 왜 빠질까?
먼저 양쪽에 연결되는 행이 있어야 남는 JOIN을 써 보자. 여기서 JOIN은 INNER JOIN과 같다.
SELECT e.id, e.name AS employee, m.name AS manager
FROM staff AS e
JOIN staff AS m ON e.manager_id = m.id
ORDER BY e.id;id employee manager
2 Jin Mira
3 Sol Mira
4 Hana JinMira의 manager_id는 NULL이다. 오른쪽 상사 역할 m에서 연결할 행을 찾을 수 없으므로, INNER JOIN은 Mira의 행을 결과에서 뺀다. Mira라는 직원이 없어진 것이 아니라, 상사와 짝이 없는 직원이 제외된 것이다.
LEFT JOIN으로 직원 네 명을 모두 남기려면?
이번에는 왼쪽 직원 e를 기준으로 남긴다. 상사와 연결되지 않아도 직원 행은 유지하고, 상사 이름만 NULL로 채운다.
도식의 왼쪽 직원 집합을 보존하면 상사가 없는 Mira도 결과에 남고 manager 열만 NULL이 된다. LEFT JOIN 결과를 직접 조회해 네 행이 유지되는지 확인하자.
SELECT e.id, e.name AS employee, m.name AS manager
FROM staff AS e
LEFT JOIN staff AS m ON e.manager_id = m.id
ORDER BY e.id;id employee manager
1 Mira NULL
2 Jin Mira
3 Sol Mira
4 Hana Jin조회 목적이 '상사가 있는 직원만'이면 INNER JOIN의 세 명이 맞다. 목적이 '모든 직원과 가능한 상사'라면 LEFT JOIN의 네 명이 맞다. 조인의 좋고 나쁨이 아니라 어떤 행을 보존해야 하는지의 차이다.
상사 없는 행을 볼 때 무엇을 더 확인할까?
이 예제에서는 manager_id IS NULL을 '상사가 없음'으로 정했다. 실제 데이터에서는 입력 누락일 수도 있으니 NULL만 보고 대표라고 단정하지 말자. 계층 구조의 최상위가 누구인지 업무 규칙으로 확인해야 한다. 상사 ID가 잘못된 값을 가리키면 LEFT JOIN에서 역시 상사 이름이 NULL로 보일 수 있으므로, 자기 참조 외래 키와 데이터 무결성도 점검할 만하다.
또 상사 이름 조건을 WHERE m.name = 'Mira'처럼 추가하면, 이 데이터에서는 Jin과 Sol만 남는다. 상사 이름이 NULL인 Mira도 다시 빠진다. LEFT JOIN만 적어 놓았다고 모든 직원이 최종 결과에 반드시 남는 것은 아니다. 최종 행 수가 중요하다면 ON과 WHERE 조건까지 함께 읽자.
핵심 요약
셀프 조인은 한 테이블을 직원·상사 두 역할로 지정해 연결한다. INNER JOIN은 짝이 있는 직원만 남기므로 상사 없는 Mira가 빠지고, LEFT JOIN은 왼쪽 직원 네 명을 모두 남긴다. 결과 건수가 예상보다 적다면 데이터부터 의심하기 전에 조인 조건과 어떤 쪽 행을 보존했는지 확인하자.
작성자
기초 개념을 구현과 검증, 실제 운영 판단까지 연결해 기록합니다.

