조인 (Join)
프로젝트에서 실제로 쓴 INNER JOIN / LEFT JOIN을 먼저 보고, 조인을 집합 관점에서 본 이론적 분류(OUTER JOIN, 등가/비등가/셀프 조인)로 이어서 정리했습니다.
조인(JOIN)
여러 테이블에 나뉘어 저장된 데이터를, 공통 컬럼(주로 FK-PK 관계)을 기준으로 한 화면에서 합쳐 보는 것이 조인입니다. 이 프로젝트는 정보를 users/reels/likes/comments로 쪼개서 저장하기 때문에, "릴스 제목과 그 업로더의 이름을 같이 보고 싶다" 같은 요구는 조인으로 해결합니다.
- INNER JOIN (교집합): 양쪽 테이블에 모두 매칭되는 행만 남깁니다. Q6에서
reels와users를reels.user_id = users.user_id로 이어 붙여 "릴스 + 업로더 이름"을 만들었고, Q7·Q9처럼comments/likes를 가운데 두고 INNER JOIN을 두 번 걸면 "댓글 -> 작성자 -> 대상 릴스", "릴스 -> 좋아요 -> 누른 사용자"까지 한 줄로 이어집니다. - LEFT JOIN (왼쪽 기준): 왼쪽(기준) 테이블의 행은 매칭이 없어도 전부 남기고, 오른쪽에 짝이 없으면 그 자리를
NULL로 채웁니다. Q8에서reels LEFT JOIN comments후WHERE comments.comment_id IS NULL조건을 걸면, "댓글이 하나도 안 달린 릴스"만 걸러낼 수 있습니다. 이 "LEFT JOIN + IS NULL"은 "한쪽에는 있는데 다른 쪽에는 없는 것"을 찾는 대표적인 패턴입니다. - ON과 WHERE의 역할 구분:
ON은 두 테이블을 어떤 조건으로 연결할지(연결 열쇠)를,WHERE는 연결된 결과에서 어떤 행만 남길지(필터)를 정합니다. Q8이 조인 조건은ON에, 걸러내는 조건(IS NULL)은WHERE에 나눠 쓴 이유입니다.
| 종류 | 남는 행 | 이 프로젝트 예시 |
|---|---|---|
INNER JOIN | 양쪽에 다 있는 행만 | Q6(릴스+업로더), Q7(댓글+작성자+릴스), Q9(릴스+좋아요 누른 사람) |
LEFT JOIN | 왼쪽 전부 + 오른쪽은 있으면 채움 | Q8(댓글 없는 릴스 = LEFT JOIN + IS NULL) |
조인의 연결 열쇠가 되는 reels.user_id에 인덱스를 건 이유("인덱스 적용" 항목 참고)도, 이렇게 user_id를 기준으로 한 조인이 자주 일어나기 때문입니다.
조인을 집합으로 보면: INNER vs OUTER
조인을 벤 다이어그램(집합)으로 생각하면 종류별 차이가 한눈에 들어옵니다. 두 테이블 A, B가 있다고 할 때:
INNER JOIN LEFT OUTER JOIN RIGHT OUTER JOIN FULL OUTER JOIN
A ∩ B A 전체 + 교집합 교집합 + B 전체 A ∪ B (합집합)
(A)(B) (A)(B) (A)(B) (A)(B)
▓▓ ██▓▓ ▓▓██ ██▓▓██
교집합만 A는 다 살리고 B는 다 살리고 둘 다 다 살리고
매칭 없으면 NULL 매칭 없으면 NULL 없는 쪽은 NULL| INNER JOIN | LEFT OUTER JOIN | RIGHT OUTER JOIN | FULL OUTER JOIN |
|---|---|---|---|
![]() | ![]() | ![]() | ![]() |
- INNER JOIN: 양쪽에 다 매칭되는 행만 남깁니다. 교집합입니다.
- LEFT OUTER JOIN: 왼쪽(기준) 테이블은 무조건 다 남기고, 오른쪽은 매칭되면 채우고 안 되면 NULL로 둡니다. "왼쪽 테이블을 기준으로 붙인다"고 생각하면 됩니다.
- RIGHT OUTER JOIN: LEFT의 반대. 오른쪽 테이블을 기준으로 전부 살립니다.
RIGHT OUTER JOIN은 사실 기준 테이블 순서만 바꾸면LEFT OUTER JOIN으로 똑같이 쓸 수 있어서, 실무에서는 LEFT만 통일해서 쓰고 RIGHT은 잘 안 쓰는 경우가 많습니다. - FULL OUTER JOIN: 양쪽 테이블의 모든 행을 다 살립니다(합집합). 매칭이 안 되는 쪽은 NULL로 채웁니다. 사실상 "기준 테이블"이라는 개념 자체가 의미 없어집니다.
조인 문법의 기본 모양은 모두 같고, JOIN 앞의 키워드만 바뀝니다.
sql
SELECT 별칭.조회할컬럼, 별칭.조회할컬럼
FROM 기준테이블 별칭
[INNER | LEFT OUTER | RIGHT OUTER | FULL OUTER] JOIN 조인테이블 별칭
ON 기준테이블별칭.기준키 = 조인테이블별칭.기준키;sql
-- 내부 조인 (교집합)
SELECT Star.Name, Dep.DepName
FROM Star
INNER JOIN Dep ON Star.DepNo = Dep.DepNo;
-- 왼쪽 외부 조인
SELECT Star.Name, Dep.Name
FROM Star
LEFT OUTER JOIN Dep ON Star.DepNo = Dep.DepNo;
-- 오른쪽 외부 조인
SELECT Star.Name, Dep.Name
FROM Star
RIGHT OUTER JOIN Dep ON Star.DepNo = Dep.DepNo;
-- 완전 외부 조인 (합집합)
SELECT Star.Name, Dep.Name
FROM Star
FULL OUTER JOIN Dep ON Star.DepNo = Dep.DepNo;그 밖에 조인 방식을 부르는 이름 몇 가지도 알아두면 좋습니다.
- 등가 조인(Equi Join):
=연산자로 매칭하는 가장 흔한 조인 (지금까지 본 예시가 전부 이 방식) - 비등가 조인(Non-Equi Join):
=가 아닌<,BETWEEN등으로 매칭하는 조인 (예: 급여가 어떤 등급 구간에 속하는지 찾기) - 셀프 조인(Self Join): 같은 테이블을 자기 자신과 조인하는 것. 사원 테이블에서 "이 사원의 상사 이름"을 찾을 때처럼, 자기 참조 관계가 있는 테이블에서 씁니다.
정리
| 종류 | 남는 행 |
|---|---|
INNER JOIN | 양쪽에 다 매칭되는 행만 (교집합) |
LEFT (OUTER) JOIN | 왼쪽 전부 + 오른쪽은 매칭 없으면 NULL (+ IS NULL로 "한쪽에만 있는 것" 찾기) |
RIGHT OUTER JOIN | 오른쪽 전부 (순서 바꾸면 LEFT와 같아 실무에선 LEFT로 통일) |
FULL OUTER JOIN | 양쪽 전부 (합집합), 없는 쪽은 NULL |
ON은 연결 조건,WHERE는 연결 결과의 필터입니다.- 매칭 방식에 따라 등가 조인(
=), 비등가 조인(<,BETWEEN), 셀프 조인(자기 자신과 조인)으로도 부릅니다.
출처: Codyssey-B1/B6-1
참고: 개인 Notion 학습 노트




