SELF JOIN은 테이블을 자기 자신과 조인하는 방법이야. 처음 보면 좀 이상하게 느껴질 수도 있는데, "왜 굳이 자기 자신이랑 조인하지?" 싶겠지? 근데 실제로 이런 상황이 꽤 자주 나와. 예를 들어, 직원 테이블이 있는데, 각 직원마다 매니저가 있어. 매니저도 직원이니까 같은 테이블에 있지. SELF JOIN을 쓰면 직원이랑 그 직원의 매니저를 쉽게 매칭할 수 있어.
좀 더 공식적으로 말하면, SELF JOIN은 그냥 일반 JOIN이랑 똑같은데, 같은 테이블을 두 번 쓰고 각각 다른 별칭(aliase)을 붙여서 구분하는 거야.
SELF JOIN은 이런 데 쓸 수 있어:
- 계층 구조 관계: "부모-자식" 관계 만들기, 예를 들면 직원과 그 직원의 매니저.
- 테이블 내부 데이터 분석: 테이블 안에서 레코드끼리 비교, 예를 들어 비슷한 상품이나 이벤트 찾기.
- 로직이 중복되는 복잡한 쿼리 짤 때.
SELF JOIN 문법
더 쉽게 이해하려면 SELF JOIN의 간단한 문법부터 볼게:
SELECT
A.column_name,
B.column_name
FROM
table_name A
JOIN
table_name B
ON
A.common_column = B.common_column;
여기서:
table_name A랑table_name B는 같은 테이블인데, 별칭만 다르게 준 거야.A.common_column이랑B.common_column은 조인할 때 기준이 되는 컬럼이야.
별칭(A랑 B)을 꼭 써야 DBMS가 "지금 어느 쪽 테이블을 쓰는지" 헷갈리지 않아.
SELF JOIN 사용 예시
예시 1: 직원과 그 매니저 리스트
자, 직원 테이블 employees가 이렇게 있다고 해보자:
| employee_id | name | manager_id |
|---|---|---|
| 1 | Alex Lin | NULL |
| 2 | Maria Chi | 1 |
| 3 | Otto Song | 1 |
| 4 | Nina Zhao | 2 |
이 테이블에서:
employee_id— 직원의 아이디.name— 직원 이름.manager_id— 매니저의 아이디(다른 직원의employee_id랑 같아).
목표: 직원과 그 직원의 매니저를 리스트로 뽑기.
SELF JOIN으로 이렇게 하면 돼:
SELECT
e.name AS employee_name,
m.name AS manager_name
FROM
employees e
LEFT JOIN
employees m
ON
e.manager_id = m.employee_id;
결과:
| employee_name | manager_name |
|---|---|
| Alex Lin | NULL |
| Maria Chi | Alex Lin |
| Otto Song | Alex Lin |
| Nina Zhao | Maria Chi |
여기서:
e테이블은 "직원" 역할이야.m테이블도 "직원"인데, "매니저" 역할로 쓰는 거지.
Alex Lin은 매니저가 없어서(manager_id = NULL) 결과에서 manager_name이 비어 있어.
예시 2: 비슷한 상품 찾기
이번엔 products 테이블이 있다고 해보자:
| product_id | product_name | category |
|---|---|---|
| 1 | 냉장고 | 전자제품 |
| 2 | 세탁기 | 전자제품 |
| 3 | 스마트폰 | 가젯 |
| 4 | 태블릿 | 가젯 |
목표: 같은 카테고리에 속한 상품 쌍을 찾기.
SELF JOIN으로 이렇게 할 수 있어:
SELECT
p1.product_name AS product_1,
p2.product_name AS product_2
FROM
products p1
JOIN
products p2
ON
p1.category = p2.category
AND
p1.product_id < p2.product_id;
결과:
| product_1 | product_2 |
|---|---|
| 냉장고 | 세탁기 |
| 스마트폰 | 태블릿 |
p1.product_id < p2.product_id 조건을 꼭 써야 해. 그래야 냉장고 — 세탁기랑 세탁기 — 냉장고처럼 중복된 쌍이 결과에 안 나와.
예시 3: 계층 구조 분석 (부모와 자식)
또 다른 예시로, categories 테이블이 있다고 하자:
| category_id | category_name | parent_id |
|---|---|---|
| 1 | 전자제품 | NULL |
| 2 | 가젯 | 1 |
| 3 | 컴퓨터 | 1 |
| 4 | 스마트폰 | 2 |
여기서:
category_id— 카테고리 아이디.category_name— 카테고리 이름.parent_id— 부모 카테고리의 아이디.
목표: 카테고리와 그 부모 카테고리를 매칭하기.
쿼리:
SELECT
c1.category_name AS child_category,
c2.category_name AS parent_category
FROM
categories c1
LEFT JOIN
categories c2
ON
c1.parent_id = c2.category_id;
결과:
| child_category | parent_category |
|---|---|
| 전자제품 | NULL |
| 가젯 | 전자제품 |
| 컴퓨터 | 전자제품 |
| 스마트폰 | 가젯 |
SELF JOIN 쓸 때 자주 하는 실수
별칭(aliase) 안 쓴 경우: 별칭을 안 쓰면 어느 쪽 테이블을 쓰는지 구분이 안 돼서 쿼리가 꼬일 수 있어.
순환 참조: 데이터에 순환 참조(예: 직원이 자기 자신이 매니저인 경우)가 있으면 결과가 이상하게 나올 수 있어.
중복 결과: 결과가 중복되지 않게(예: p1.product_id < p2.product_id처럼) 꼭 필터링을 해줘야 해.
SELF JOIN은 데이터 다룰 때 진짜 강력한 도구야. 잘만 쓰면 계층 구조, 테이블 내부 관계, 데이터 분석 등 복잡한 문제도 쉽게 풀 수 있어. 이제 SQL 세계에서 이 "셀카"가 얼마나 유용한지 알겠지?
GO TO FULL VERSION