오늘은 데이터 합치기 중에서 제일 자유로운 방식인 FULL OUTER JOIN을 알아볼 거야. 이 방식은 짝이 없어도 결과에 다 들어가니까, 아무나 다 환영이야.
FULL OUTER JOIN은 두 테이블의 모든 행을 다 반환하는 데이터 합치기야. 한 테이블에만 있고 다른 테이블에 짝이 없는 행은, 없는 값 자리에 NULL이 들어가. 이건 마치 두 파티에 온 사람들 명단을 다 합치는 거랑 비슷해. 한 파티만 온 사람도 명단에 다 들어가는 거지.
시각적으로 보면 이렇게 돼:
테이블 A 테이블 B
+----+----------+ +----+----------+
| id | name | | id | course |
+----+----------+ +----+----------+
| 1 | Alice | | 2 | Math |
| 2 | Bob | | 3 | Physics |
| 4 | Charlie | | 5 | History |
+----+----------+ +----+----------+
FULL OUTER JOIN 결과:
+----+----------+----------+
| id | name | course |
+----+----------+----------+
| 1 | Alice | NULL |
| 2 | Bob | Math |
| 3 | NULL | Physics |
| 4 | Charlie | NULL |
| 5 | NULL | History |
+----+----------+----------+
짝이 없는 행도 다 남아있고, 없는 컬럼 값은 NULL로 채워져.
FULL OUTER JOIN 문법
문법은 간단하지만, 진짜 강력해:
SELECT
컬럼들
FROM
테이블1
FULL OUTER JOIN
테이블2
ON 테이블1.공통_컬럼 = 테이블2.공통_컬럼;
여기서 핵심은 FULL OUTER JOIN이야. PostgreSQL이 두 테이블의 모든 행을 다 가져오게 해줘. ON 조건에 맞는 짝이 없으면, 그 값은 NULL로 채워져.
사용 예시
이제 친숙한 university 데이터베이스의 students랑 enrollments 테이블로 실제 예제를 볼게.
예제 1: 모든 학생과 강좌 리스트
두 테이블이 있다고 해보자:
students 테이블:
| student_id | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
enrollments 테이블:
| enrollment_id | student_id | course |
|---|---|---|
| 101 | 1 | Math |
| 102 | 2 | Physics |
| 103 | 4 | History |
우리 목표는, 강좌에 등록 안 한 학생도, 학생이 없는 강좌도 다 포함해서 학생과 강좌 전체 리스트를 만드는 거야.
이렇게 쿼리하면 돼:
SELECT
s.student_id,
s.name,
e.course
FROM
students s
FULL OUTER JOIN
enrollments e
ON
s.student_id = e.student_id;
결과:
| student_id | name | course |
|---|---|---|
| 1 | Alice | Math |
| 2 | Bob | Physics |
| 3 | Charlie | NULL |
| NULL | NULL | History |
보다시피, 모든 학생과 모든 강좌가 결과에 들어가. Charlie는 강좌에 등록 안 했으니까 course가 NULL이고, History는 학생이 없어서 student_id랑 name이 NULL이야.
예제 2: 판매와 상품 분석
이번엔 가게를 생각해보자. 두 테이블이 있어:
products 테이블:
| product_id | name |
|---|---|
| 1 | Laptop |
| 2 | Smartphone |
| 3 | Printer |
sales 테이블:
| sale_id | product_id | quantity |
|---|---|---|
| 101 | 1 | 5 |
| 102 | 3 | 2 |
| 103 | 4 | 10 |
우리는, 판매 안 된 상품도, 잘못된 product_id로 기록된 판매도 다 포함해서 전체 상품과 판매 리스트를 보고 싶어.
쿼리는 이렇게:
SELECT
p.product_id,
p.name AS product_name,
s.quantity
FROM
products p
FULL OUTER JOIN
sales s
ON
p.product_id = s.product_id;
결과:
| product_id | product_name | quantity |
|---|---|---|
| 1 | Laptop | 5 |
| 2 | Smartphone | NULL |
| 3 | Printer | 2 |
| NULL | NULL | 10 |
여기서 Smartphone은 판매가 없어서 (quantity = NULL), product_id = 4로 기록된 판매는 상품이랑 매칭이 안 돼.
실습 문제
departments랑 employees 테이블로 쿼리 한번 짜볼래?
departments 테이블:
| department_id | department_name |
|---|---|
| 1 | HR |
| 2 | IT |
| 3 | Marketing |
employees 테이블:
| employee_id | department_id | name |
|---|---|---|
| 101 | 1 | Alice |
| 102 | 2 | Bob |
| 103 | 4 | Charlie |
FULL OUTER JOIN을 써서 모든 부서와 직원 리스트를 만들어봐. 없는 데이터는 NULL로 채워줘.
NULL 값 처리하는 방법
NULL 값 문제는 FULL OUTER JOIN을 쓰면 꼭 따라오는 거야. 실제로는 NULL 대신 더 의미 있는 값으로 바꿔야 할 때가 많아. PostgreSQL에서는 COALESCE() 함수로 쉽게 할 수 있어.
예시:
SELECT
COALESCE(s.name, '학생 없음') AS student_name,
COALESCE(e.course, '강좌 없음') AS course_name
FROM
students s
FULL OUTER JOIN
enrollments e
ON
s.student_id = e.student_id;
결과:
| student_name | course_name |
|---|---|
| Alice | Math |
| Bob | Physics |
| Charlie | 강좌 없음 |
| 학생 없음 | History |
이제 NULL 대신에 더 알아보기 쉬운 값이 들어가서, 리포트가 훨씬 보기 좋아졌지.
FULL OUTER JOIN 언제 써야 할까?
FULL OUTER JOIN은 모든 데이터를 다 보고 싶을 때, 즉 두 테이블이 완전히 연결 안 돼도 다 보여야 할 때 유용해. 예를 들면:
- 판매와 상품 리포트 — 팔린 상품, 안 팔린 상품 다 보고 싶을 때.
- 학생과 강좌 분석 — 누락된 데이터가 있는지 확인할 때.
- 리스트 비교 — 두 데이터셋의 차이점 찾을 때.
이 강의가 FULL OUTER JOIN에 대해 잘 이해할 수 있게 도와줬길 바래! 이제 더 복잡한 조인과 데이터 처리의 세계로 가보자!
GO TO FULL VERSION