MySQL 3-Table INNER JOIN — 다중 테이블 조인 완전 정리
3테이블 INNER JOIN은 한 번에 세 테이블을 모두 연결하는 것이 아니라, 학생과 소속 테이블을 먼저 연결하고 그 결과를 다시 동아리 테이블과 연결한다고 읽으면 쉽다.
| clubName | roomNo | stdName | addr | 해석 |
|---|---|---|---|---|
| 수영 | 101호 | 김범수 | 경기 | 학생과 동아리 정보가 모두 매칭됨 |
| 바둑 | 202호 | NULL | NULL | OUTER JOIN에서는 매칭 없는 쪽이 NULL로 남을 수 있음 |
학생과 동아리는 직접 연결되는 것이 아니라 중간 테이블을 통해 연결된다. 이 구조를 이해하면 다대다 관계의 JOIN이 훨씬 쉬워진다.
stdtbl에는 학생 정보, stdclubtbl에는 학생과 동아리의 연결, clubtbl에는 동아리 정보가 있다. 중간 테이블을 거쳐야 학생이 어떤 동아리에 속했는지 알 수 있다.
S.stdName = SC.stdName 조건은 학생 기본 정보와 동아리 소속 기록을 같은 학생 이름으로 연결한다.
SC.clubName = C.clubName 조건은 소속 기록에 적힌 동아리명과 실제 동아리 정보를 연결한다.
ORDER BY S.stdName은 학생 중심 목록이고, ORDER BY C.clubName은 동아리 중심 목록으로 읽힌다.
학생 한 명이 여러 동아리에 가입할 수 있고, 동아리 하나에도 여러 학생이 가입할 수 있다면 학생 테이블과 동아리 테이블만으로는 관계를 깔끔하게 저장하기 어렵다. 그래서 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로 중복 여부를 검사하는 습관이 필요하다.
3테이블 INNER JOIN은 중간 테이블을 통해 양쪽 테이블의 관계를 연결하는 패턴이다. 아래처럼 먼저 연결 경로를 주석으로 적고 SQL을 작성하면 ON 조건 누락을 줄일 수 있다.
| 확인 항목 | 보는 이유 | 판단 기준 |
|---|---|---|
| 학생 수와 결과 행 수 비교 | 한 학생이 여러 동아리에 가입하면 행이 늘어난다 | 중복이 자연스러운지 확인 |
| 중간 테이블 단독 조회 | JOIN 결과의 기준 관계를 확인한다 | stdName, clubName 조합이 맞는지 확인 |
| ORDER BY 추가 | 결과 검토를 쉽게 만든다 | 학생명, 동아리명 순서로 정렬 |
| SELECT * 지양 | 동일한 이름의 컬럼이 섞인다 | 필요한 컬럼만 별칭과 함께 선택 |
| 질문 | 확인 포인트 |
|---|---|
| 기준 테이블이 무엇인가? | FROM에 둔 테이블이 결과 보존의 출발점이다. |
| 관계 테이블을 빠뜨리지 않았는가? | N:M 관계는 중간 테이블을 거쳐야 한다. |
| NULL이 정상 신호인가? | OUTER JOIN에서는 매칭 실패를 나타내는 정상 결과일 수 있다. |
| 결과 행 수가 늘어난 이유는? | 1:N 또는 N:M 관계가 펼쳐졌는지 먼저 확인한다. |
핵심 요약
Tags
'php' 카테고리의 다른 글
| MySQL 3-Table OUTER JOIN — 혼합 외부 조인 완전 정리 (0) | 2026.06.28 |
|---|---|
| MySQL OUTER JOIN — LEFT/RIGHT 외부 조인 완전 정리 (0) | 2026.06.28 |
| MySQL WHERE EXISTS — EXISTS 서브쿼리 완전 정리 (0) | 2026.06.28 |
| MySQL JOIN 테이블 별칭 — B.컬럼명 축약 완전 정리 (0) | 2026.06.28 |
| MySQL 표준 JOIN — 테이블명.컬럼명 완전 정리 (0) | 2026.06.28 |
왕진 블로그

댓글