Skip to content

조인 (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 JOINLEFT OUTER JOINRIGHT OUTER JOINFULL OUTER JOIN
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 학습 노트