SQL Server(Transact-SQL)에서 조인(JOIN)은 두 개 이상의 테이블을 연결하여 데이터를 조회할 때 사용합니다. 테이블 간의 관계(주로 외래 키)를 기반으로 데이터를 결합하며, 조인 조건에 따라 결과 집합이 달라집니다.
SQL Server의 4가지 주요 조인 유형
- INNER JOIN (내부 조인): 양쪽 테이블 모두에 일치하는 행만 반환
- LEFT OUTER JOIN (왼쪽 외부 조인): 왼쪽 테이블의 모든 행과 오른쪽 테이블의 일치하는 행 반환
- RIGHT OUTER JOIN (오른쪽 외부 조인): 오른쪽 테이블의 모든 행과 왼쪽 테이블의 일치하는 행 반환
- FULL OUTER JOIN (완전 외부 조인): 양쪽 테이블의 모든 행 반환, 일치하지 않으면 NULL
1. INNER JOIN (내부 조인)
가장 일반적인 조인 방식으로, 조인 조건을 만족하는 양쪽 테이블의 행만 결과로 반환합니다. 일치하지 않는 행은 제외됩니다.
문법
SELECT 열_목록
FROM 테이블1
INNER JOIN 테이블2
ON 테이블1.공통_열 = 테이블2.공통_열;
※ INNER 키워드는 생략 가능하며, 단순히 JOIN만 작성해도 내부 조인으로 동작합니다.
예제: 공급업체(Suppliers)와 주문(Orders) 테이블
샘플 데이터
| 공급업체 테이블 (suppliers) | |
|---|---|
| supplier_id | supplier_name |
| 10000 | IBM |
| 10001 | Hewlett Packard |
| 10002 | Microsoft |
| 10003 | NVIDIA |
| 주문 테이블 (orders) | ||
|---|---|---|
| order_id | supplier_id | order_date |
| 500125 | 10000 | 2003-05-12 |
| 500126 | 10001 | 2003-05-13 |
| 500127 | 10004 | 2003-05-14 |
쿼리
SELECT s.supplier_id, s.supplier_name, o.order_date
FROM suppliers s
INNER JOIN orders o
ON s.supplier_id = o.supplier_id;
결과
| supplier_id | supplier_name | order_date |
|---|---|---|
| 10000 | IBM | 2003-05-12 |
| 10001 | Hewlett Packard | 2003-05-13 |
해설: Microsoft(10002)와 NVIDIA(10003)는 주문 테이블에 일치하는 행이 없어 제외되었습니다. 주문 ID 500127(supplier_id 10004)은 공급업체 테이블에 해당 ID가 없어 제외되었습니다.
구문(Old Syntax) - 권장하지 않음
SELECT s.supplier_id, s.supplier_name, o.order_date
FROM suppliers s, orders o
WHERE s.supplier_id = o.supplier_id;
ANSI SQL-92 표준인 명시적 JOIN 문법(INNER JOIN ... ON)을 사용하는 것이 가독성과 유지보수에 유리합니다.
2. LEFT OUTER JOIN (왼쪽 외부 조인)
왼쪽 테이블(첫 번째 테이블)의 모든 행을 반환하고, 오른쪽 테이블에서 조인 조건과 일치하는 행만 결합합니다. 오른쪽 테이블에 일치하는 행이 없으면 NULL로 채워집니다.
문법
SELECT 열_목록
FROM 테이블1
LEFT [OUTER] JOIN 테이블2
ON 테이블1.공통_열 = 테이블2.공통_열;
예제
앞서 본 공급업체 테이블을 왼쪽, 주문 테이블을 오른쪽으로 하여 LEFT JOIN을 수행합니다.
쿼리
SELECT s.supplier_id, s.supplier_name, o.order_date
FROM suppliers s
LEFT OUTER JOIN orders o
ON s.supplier_id = o.supplier_id;
결과
| supplier_id | supplier_name | order_date |
|---|---|---|
| 10000 | IBM | 2003-05-12 |
| 10001 | Hewlett Packard | 2003-05-13 |
| 10002 | Microsoft | NULL |
| 10003 | NVIDIA | NULL |
해설: 모든 공급업체가 결과에 포함됩니다. 주문 내역이 없는 Microsoft와 NVIDIA의 order_date는 NULL로 표시됩니다.
3. RIGHT OUTER JOIN (오른쪽 외부 조인)
오른쪽 테이블(두 번째 테이블)의 모든 행을 반환하고, 왼쪽 테이블에서 조인 조건과 일치하는 행만 결합합니다. 왼쪽 테이블에 일치하는 행이 없으면 NULL로 채워집니다. LEFT JOIN과 방향만 반대입니다.
문법
SELECT 열_목록
FROM 테이블1
RIGHT [OUTER] JOIN 테이블2
ON 테이블1.공통_열 = 테이블2.공통_열;
예제
샘플 데이터
| 공급업체 테이블 (suppliers) | |
|---|---|
| supplier_id | supplier_name |
| 10000 | Apple |
| 10001 | |
| 주문 테이블 (orders) | ||
|---|---|---|
| order_id | supplier_id | order_date |
| 500125 | 10000 | 2003-08-12 |
| 500126 | 10001 | 2003-08-13 |
| 500127 | 10002 | 2003-08-14 |
쿼리
SELECT o.order_id, o.order_date, s.supplier_name
FROM suppliers s
RIGHT OUTER JOIN orders o
ON s.supplier_id = o.supplier_id;
결과
| order_id | order_date | supplier_name |
|---|---|---|
| 500125 | 2003-08-12 | Apple |
| 500126 | 2003-08-13 | |
| 500127 | 2003-08-14 | NULL |
해설: 모든 주문 내역이 결과에 포함됩니다. 주문 ID 500127(supplier_id 10002)은 공급업체 테이블에 매칭되는 행이 없어 supplier_name이 NULL로 표시됩니다.
4. FULL OUTER JOIN (완전 외부 조인)
양쪽 테이블의 모든 행을 반환합니다. 조인 조건이 일치하면 데이터를 결합하고, 일치하지 않는 쪽은 NULL로 채웁니다. LEFT JOIN과 RIGHT JOIN의 합집합(Union)과 유사한 결과를 냅니다.
문법
SELECT 열_목록
FROM 테이블1
FULL [OUTER] JOIN 테이블2
ON 테이블1.공통_열 = 테이블2.공통_열;
예제
샘플 데이터
| 공급업체 테이블 (suppliers) | |
|---|---|
| supplier_id | supplier_name |
| 10000 | IBM |
| 10001 | Hewlett Packard |
| 10002 | Microsoft |
| 10003 | NVIDIA |
| 주문 테이블 (orders) | ||
|---|---|---|
| order_id | supplier_id | order_date |
| 500125 | 10000 | 2003-08-12 |
| 500126 | 10001 | 2003-08-13 |
| 500127 | 10004 | 2003-08-14 |
쿼리
SELECT s.supplier_id, s.supplier_name, o.order_date
FROM suppliers s
FULL OUTER JOIN orders o
ON s.supplier_id = o.supplier_id;
결과
| supplier_id | supplier_name | order_date |
|---|---|---|
| 10000 | IBM | 2003-08-12 |
| 10001 | Hewlett Packard | 2003-08-13 |
| 10002 | Microsoft | NULL |
| 10003 | NVIDIA | NULL |
| 10004 | NULL | 2003-08-14 |
해설: 모든 공급업체와 모든 주문이 결과에 포함됩니다. 매칭되지 않는 공급업체(Microsoft, NVIDIA)는 order_date가 NULL, 매칭되지 않는 주문(supplier_id 10004)은 supplier_name이 NULL로 표시됩니다.
요약 및 선택 가이드
| 조인 유형 | 반환 행 | 주요 용도 |
|---|---|---|
| INNER JOIN | 양쪽 모두 일치하는 행만 | 관계가 확정된 데이터만 필요할 때 (가장 많이 사용) |
| LEFT JOIN | 왼쪽 전부 + 오른쪽 매칭 | 기준 테이블(왼쪽) 기준 전체 현황 파악, 누락 데이터 확인 |
| RIGHT JOIN | 오른쪽 전부 + 왼쪽 매칭 | LEFT JOIN으로 테이블 순서만 바꾸면 되므로 실무에서 덜 사용 |
| FULL JOIN | 양쪽 전부 (일치 안 하면 NULL) | 두 테이블의 전체 데이터 비교, 데이터 정합성 검증 |
팁: 실무에서는 LEFT JOIN을 기준으로 테이블 순서를 조정하여 사용하는 것이 일반적입니다. RIGHT JOIN은 쿼리 가독성을 해칠 수 있으므로 테이블 순서를 바꿔 LEFT JOIN으로 작성하는 것을 권장합니다.