조인(LEFT / INNER / RIGHT) 완전 정리 — 개념 · 예제 · 활용 팁

데이터베이스 조인을 한 번에 이해하기 쉽도록 개념 · 시각화 · SQL 예제 · 결과 표까지 정리했습니다. 초보자도 빠르게 핵심을 잡고, 실무에서 어떤 조인을 써야 할지 판단할 수 있게 구성했습니다.
- INNER JOIN: 양쪽 테이블에 모두 존재하는 교집합만 반환
- LEFT JOIN: 왼쪽(기준) 테이블의 모든 행 + 오른쪽 일치값(없으면 NULL)
- RIGHT JOIN: 오른쪽(기준) 테이블의 모든 행 + 왼쪽 일치값(없으면 NULL)
- 조인은 읽기 관점의 연산 — 결과를 이해하려면 항상
예상 결과 표를 떠올리세요.
1) 직관적인 시각화 (Venn 다이어그램)
이 그림에서 INNER는 두 원의 겹치는 부분, LEFT는 왼쪽 원 전체(겹침+왼쪽 전용), RIGHT는 오른쪽 원 전체(겹침+오른쪽 전용)을 의미합니다.
2) 실전 예제 — 테이블과 데이터
아래 예제는 흔히 등장하는 사용자(users)와 주문(orders) 테이블입니다.
| id | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Carol |
| id | user_id | product |
|---|---|---|
| 101 | 1 | Book |
| 102 | 2 | Pen |
| 103 | 4 | Bag |
참고: orders.user_id = 4 인 주문(103)은 users에 매칭되는 사용자 없음 — 이 행이 조인 결과에서 어떻게 처리되는지가 핵심입니다.
3) INNER JOIN (교집합)
양쪽 테이블에 모두 존재하는 행만 결과로 반환합니다. 매칭되는 키가 없는 행은 제외됩니다.
-- SQL
SELECT u.id AS user_id, u.name, o.id AS order_id, o.product
FROM users u
INNER JOIN orders o
ON u.id = o.user_id;
결과(행):
| user_id | name | order_id | product |
|---|---|---|---|
| 1 | Alice | 101 | Book |
| 2 | Bob | 102 | Pen |
해설: user_id = 4(orders 103)은 users에 없으므로 결과에서 제외됩니다.
4) LEFT JOIN (왼쪽 기준 전부)
왼쪽 테이블의 모든 행을 반환하고, 오른쪽에 매칭되는 값이 없으면 NULL로 채웁니다.
-- SQL
SELECT u.id AS user_id, u.name, o.id AS order_id, o.product
FROM users u
LEFT JOIN orders o
ON u.id = o.user_id
ORDER BY u.id;
결과(행):
| user_id | name | order_id | product |
|---|---|---|---|
| 1 | Alice | 101 | Book |
| 2 | Bob | 102 | Pen |
| 3 | Carol | NULL | NULL |
해설: Carol(사용자 id=3)은 주문이 없지만 LEFT JOIN은 users의 모든 행을 보존합니다.
5) RIGHT JOIN (오른쪽 기준 전부)
RIGHT JOIN은 LEFT JOIN의 거울입니다. 오른쪽 테이블의 모든 행을 반환하고 왼쪽에 매칭되지 않으면 NULL로 채웁니다. (많은 DB에서는 RIGHT 대신 LEFT로 표현하는 편이 가독성에 유리합니다.)
-- SQL
SELECT u.id AS user_id, u.name, o.id AS order_id, o.product
FROM users u
RIGHT JOIN orders o
ON u.id = o.user_id
ORDER BY o.id;
결과(행):
| user_id | name | order_id | product |
|---|---|---|---|
| 1 | Alice | 101 | Book |
| 2 | Bob | 102 | Pen |
| NULL | NULL | 103 | Bag |
해설: orders.user_id=4인 103 행은 users에 매칭되지 않으므로 user 컬럼들은 NULL이 됩니다.
6) FULL OUTER JOIN (양쪽 모두 보존) — 일부 DB에서만 지원
FULL OUTER JOIN은 왼쪽과 오른쪽의 모든 행을 반환하고 매칭되지 않는 부분은 NULL로 채웁니다. MySQL은 직접 지원하지 않아 UNION으로 흉내냅니다.
-- PostgreSQL
SELECT *
FROM users u
FULL OUTER JOIN orders o
ON u.id = o.user_id;
-- MySQL 흉내 (예시)
SELECT u.*, o.* FROM users u LEFT JOIN orders o ON u.id=o.user_id
UNION
SELECT u.*, o.* FROM users u RIGHT JOIN orders o ON u.id=o.user_id;
7) 그 외 조인 유형·문법 팁
- CROSS JOIN: 카티션 곱(모든 조합). 주의해서 사용 — WHERE절로 필터링하지 않으면 폭발적 결과 발생.
- SELF JOIN: 같은 테이블을 두 번 참조할 때 사용(별칭 필요). 예: 직원의 매니저를 찾을 때.
- USING(col) / NATURAL JOIN: 공통 컬럼 이름이 있을 때 간단히 쓰는 문법(명시적 ON이 더 안전).
- 조인 순서: SQL 표준상 조인의 논리적 의미는 같지만, 실행계획(실행속도)은 쿼리 플래너가 결정 — EXPLAIN으로 확인하세요.
8) 성능 관점에서의 실무 팁
- 조인 키에 인덱스을 걸어라 — 조인 성능에 가장 큰 영향
- 필요한 컬럼만 SELECT — 넓은 열(LOB 등)은 네트워크·I/O를 늘림
- 큰 테이블 조인 순서와 필터링(WHERE/HAVING)을 조절해 중간 결과 크기 줄이기
- EXPLAIN / EXPLAIN ANALYZE로 실제 실행계획과 비용 확인
- 복잡한 조인은 뷰나 임시테이블로 나누어 테스트하면 가독성과 튜닝이 쉬워짐
9) 자주 하는 실수 & 체크리스트
- 조인 결과를 예상하지 않고 바로 업데이트/삭제 작업 수행 — 항상 SELECT로 결과 검증
- NULL 비교 실수:
= NULL은 항상 FALSE —IS NULL사용 - 복합키 조인 시 컬럼 순서를 실수 — ON 절과 인덱스가 일치하는지 확인
- JOIN 대신 서브쿼리를 남발 — 경우에 따라 서브쿼리가 느릴 수 있음. EXPLAIN으로 비교
10) 빠른 비교표
| 조인 | 반환 행 | 주용도 | 주의 |
|---|---|---|---|
| INNER JOIN | 교집합 | 매칭된 데이터만 조회 | 매칭되지 않는 행 손실 |
| LEFT JOIN | 왼쪽 모두 + 오른쪽 매칭 | 기준 테이블 보존 | NULL 처리 확인 |
| RIGHT JOIN | 오른쪽 모두 + 왼쪽 매칭 | 오른쪽을 기준으로 보존 | 가독성 위해 LEFT로 재작성 권장 |
마무리 — 작은 테스트로 결과를 확인하세요
조인을 처음 설계할 때는 작은 샘플 데이터로 SELECT 결과를 눈으로 확인하는 습관이 가장 안전합니다. 쿼리 실행 계획(EXPLAIN)과 인덱스 상태도 함께 확인해 성능 문제를 예방하세요.
'개발 · IT > 백엔드' 카테고리의 다른 글
| MySQL 쿼리 최적화 방법 10가지 (0) | 2025.11.18 |
|---|---|
| 트랜잭션 ACID 쉽게 이해하기 — 핵심 개념 · 예시 · 실무 팁 (0) | 2025.11.17 |
| DB 인덱스 개념과 성능 비교 — 쉽게 이해하는 실전 가이드 (0) | 2025.11.16 |
| 실무에서 자주 쓰는 SQL 튜닝 기법 성능 최적화 가이드 (0) | 2025.11.14 |
| Node.js 모듈 전쟁: CJS vs ESM, 지금 시작할 때 선택은? (0) | 2025.10.30 |
댓글