MySQL OUTER JOIN — LEFT/RIGHT 외부 조인 완전 정리
OUTER JOIN은 한쪽 테이블의 행을 모두 보존한다. 회원은 가입했지만 구매 이력이 없는 사람까지 보고 싶다면 usertbl을 보존하는 LEFT OUTER JOIN이 적합하다.
| clubName | roomNo | stdName | addr | 해석 |
|---|---|---|---|---|
| 수영 | 101호 | 김범수 | 경기 | 학생과 동아리 정보가 모두 매칭됨 |
| 바둑 | 202호 | NULL | NULL | OUTER JOIN에서는 매칭 없는 쪽이 NULL로 남을 수 있음 |
학생과 동아리는 직접 연결되는 것이 아니라 중간 테이블을 통해 연결된다. 이 구조를 이해하면 다대다 관계의 JOIN이 훨씬 쉬워진다.
FROM usertbl U LEFT OUTER JOIN buytbl B는 회원 테이블의 모든 회원을 결과에 남긴다.
구매 테이블에 매칭되는 행이 없으면 B.prodName 같은 구매 컬럼은 NULL로 표시된다.
FROM buytbl B RIGHT OUTER JOIN usertbl U는 오른쪽 usertbl을 보존하므로 위 LEFT JOIN과 같은 관점의 결과를 낼 수 있다.
기준 테이블을 FROM에 먼저 놓고 LEFT JOIN으로 붙이는 방식이 읽기 쉽고 유지보수도 편하다.
학생 한 명이 여러 동아리에 가입할 수 있고, 동아리 하나에도 여러 학생이 가입할 수 있다면 학생 테이블과 동아리 테이블만으로는 관계를 깔끔하게 저장하기 어렵다. 그래서 stdclubtbl 같은 중간 테이블이 필요하다.
| 테이블 | 역할 | 주요 컬럼 |
|---|---|---|
| stdtbl | 학생 기본 정보 | stdName, addr |
| stdclubtbl | 학생-동아리 관계 | stdName, clubName |
| clubtbl | 동아리 기본 정보 | clubName, roomNo |
RIGHT OUTER JOIN은 기준 테이블을 오른쪽에 둔 표현이다. 같은 결과를 더 읽기 쉽게 만들고 싶다면 테이블 순서를 바꿔 LEFT OUTER JOIN으로 표현할 수 있다.
OUTER JOIN 결과에서 NULL은 오류가 아니라 "매칭되는 행이 없었다"는 신호다. 이 신호를 이용하면 구매 이력이 없는 회원, 가입 학생이 없는 동아리 같은 데이터를 찾을 수 있다.
| NULL 위치 | 의미 | 확인 방법 |
|---|---|---|
| 구매 컬럼 NULL | 회원은 있지만 구매 이력이 없음 | B.userID IS NULL |
| 학생 컬럼 NULL | 동아리는 있지만 소속 학생이 없음 | S.stdName IS NULL |
| 동아리 컬럼 NULL | 학생 소속 기록은 있지만 동아리 원장이 없음 | C.clubName IS NULL |
| 주소 NULL | 회원 또는 학생 기본 정보가 매칭되지 않음 | 기준 테이블을 단독 조회 |
| 실수 | 증상 | 해결 |
|---|---|---|
| 3테이블 조인에서 ON 조건 하나 누락 | 중복 행이 크게 늘어난다 | JOIN마다 ON이 하나씩 있는지 확인 |
| LEFT와 RIGHT를 섞어 읽음 | 어느 테이블이 보존되는지 헷갈린다 | 가능하면 LEFT JOIN 중심으로 재작성 |
| NULL을 데이터 오류로 오해 | OUTER JOIN의 정상 결과를 잘못 판단 | 매칭 없음의 신호로 해석 |
| 중간 테이블을 건너뜀 | 학생과 동아리 관계가 연결되지 않음 | stdclubtbl을 반드시 거쳐 조인 |
| 정렬 기준 생략 | 출력 순서가 매번 달라 보인다 | 학생명 또는 동아리명으로 ORDER BY |
다중 조인은 테이블 수가 늘수록 결과 행 수가 예상과 달라지기 쉽다. 작은 테스트 데이터로 먼저 확인하고, 실제 데이터에서는 COUNT와 GROUP BY로 중복 여부를 검사하는 습관이 필요하다.
OUTER JOIN은 “매칭되지 않은 데이터”를 찾을 때 가장 자주 쓴다. 아래 예제는 구매 이력이 없는 회원을 찾는 전형적인 패턴이다.
| 목적 | JOIN 선택 | WHERE 조건 |
|---|---|---|
| 구매 없는 회원 | 회원 LEFT JOIN 구매 | B.userID IS NULL |
| 회원 없는 구매 내역 | 구매 LEFT JOIN 회원 | U.userID IS NULL |
| 전체 회원과 구매 요약 | 회원 LEFT JOIN 구매 | GROUP BY U.userID |
| 매칭된 데이터만 보기 | INNER JOIN | NULL 조건 없음 |
| 질문 | 확인 포인트 |
|---|---|
| 기준 테이블이 무엇인가? | FROM에 둔 테이블이 결과 보존의 출발점이다. |
| 관계 테이블을 빠뜨리지 않았는가? | N:M 관계는 중간 테이블을 거쳐야 한다. |
| NULL이 정상 신호인가? | OUTER JOIN에서는 매칭 실패를 나타내는 정상 결과일 수 있다. |
| 결과 행 수가 늘어난 이유는? | 1:N 또는 N:M 관계가 펼쳐졌는지 먼저 확인한다. |
핵심 요약
Tags
'php' 카테고리의 다른 글
| MySQL CROSS JOIN · COUNT — 카르테시안 곱 완전 정리 (0) | 2026.06.29 |
|---|---|
| MySQL 3-Table OUTER JOIN — 혼합 외부 조인 완전 정리 (0) | 2026.06.28 |
| MySQL 3-Table INNER JOIN — 다중 테이블 조인 완전 정리 (0) | 2026.06.28 |
| MySQL WHERE EXISTS — EXISTS 서브쿼리 완전 정리 (0) | 2026.06.28 |
| MySQL JOIN 테이블 별칭 — B.컬럼명 축약 완전 정리 (0) | 2026.06.28 |
왕진 블로그

댓글