모든 강의를 무료로 볼 수 있어요. 회원가입 없이도 학습 가능합니다.

15강 / 전체 24강

다중 조인

10분 읽기 조회 0

세 개 이상 테이블을 조인할 때 관계를 따라가는 전략, INNER와 LEFT JOIN 혼합, 셀프 조인 개념까지 다룹니다.

🎯 학습 목표

이 강을 마치면 세 개 이상의 테이블을 조인할 때 관계를 따라가며 쿼리를 체계적으로 설계하는 전략을 갖출 수 있습니다. INNER JOIN과 LEFT JOIN을 혼합해 상황에 맞는 조인 유형을 선택하고, 같은 테이블을 두 번 조인하는 셀프 조인(Self Join)의 개념도 이해할 수 있게 됩니다. 실무에서 마주치는 복잡한 쿼리를 두려움 없이 분해하고 작성할 수 있습니다.

🗺️ 다중 조인 설계 전략

이 섹션에서는 여러 테이블을 조인할 때 쿼리를 어떻게 설계하는지 전략적 접근 방법을 살펴보겠습니다.

13강에서 세 테이블(orders, members, books)을 한 번에 조인했습니다. 테이블이 더 늘어나도 기본 원칙은 동일합니다. 복잡한 다중 조인을 작성할 때는 다음 단계로 접근합니다.

첫째로 "중심 테이블"을 정합니다. 보통 가장 많은 외래키를 가진 테이블이 중심이 됩니다. 우리 예시에서는 orders 테이블이 member_id와 book_id 두 개의 외래키를 가지므로 중심입니다.

둘째로 중심 테이블에서 뻗어나가는 관계를 하나씩 따라갑니다. orders → members(회원 정보), orders → books(도서 정보)처럼 연결 방향을 파악합니다.

셋째로 각 조인마다 적합한 JOIN 유형을 선택합니다. 반드시 일치해야 하면 INNER JOIN, 일치 여부와 관계없이 왼쪽을 유지해야 하면 LEFT JOIN입니다.

-- 조인 구조 설계 도식:
-- orders (중심)
--   ├─ INNER JOIN members  (회원 정보)
--   └─ INNER JOIN books    (도서 정보)

SELECT
  o.order_id,
  m.name        AS 회원이름,
  b.title       AS 도서제목,
  b.price * o.quantity AS 주문금액,
  o.status
FROM orders AS o
INNER JOIN members AS m ON o.member_id = m.member_id
INNER JOIN books   AS b ON o.book_id   = b.book_id;

이처럼 중심 테이블(FROM)에서 시작해 JOIN을 차례로 추가하면 복잡한 다중 조인도 체계적으로 작성할 수 있습니다.

🔀 INNER JOIN + LEFT JOIN 혼합

이 섹션에서는 하나의 쿼리 안에서 INNER JOIN과 LEFT JOIN을 목적에 따라 다르게 사용하는 방법을 살펴보겠습니다.

실무에서는 조인마다 다른 유형을 선택해야 하는 경우가 많습니다. 예를 들어 "주문 정보와 회원 정보는 반드시 일치해야 하지만, 리뷰는 없을 수도 있다"는 상황이 있다면 INNER JOIN과 LEFT JOIN을 혼합합니다.

우리 실습 DB의 세 테이블을 활용한 혼합 예시입니다. "모든 회원과 그들의 주문 정보 — 주문이 있다면 도서 제목도 함께"를 쿼리로 표현합니다.

-- 모든 회원 + 주문(없어도 포함) + 주문 있으면 도서 정보
SELECT
  m.member_id,
  m.name          AS 회원이름,
  m.grade,
  o.order_id      AS 주문번호,
  b.title         AS 도서제목,
  o.order_date,
  o.status
FROM members AS m
LEFT JOIN orders AS o ON m.member_id = o.member_id
LEFT JOIN books  AS b ON o.book_id   = b.book_id
ORDER BY m.member_id, o.order_date;

두 조인 모두 LEFT JOIN을 사용합니다. 주문 없는 회원은 order_id, title, order_date, status가 모두 NULL로 표시됩니다. 주문은 있지만 도서 정보가 NULL인 경우(데이터 이상)도 회원과 주문은 유지됩니다.

반면 "완료된 주문의 회원 + 도서 정보"는 INNER JOIN이 적합합니다.

-- 완료된 주문만: 회원 + 도서 + 통계
SELECT
  m.name                        AS 회원이름,
  b.title                       AS 도서제목,
  b.category,
  SUM(o.quantity)               AS 총구매수량,
  SUM(b.price * o.quantity)     AS 총구매금액
FROM orders AS o
INNER JOIN members AS m ON o.member_id = m.member_id
INNER JOIN books   AS b ON o.book_id   = b.book_id
WHERE o.status = 'DONE'
GROUP BY m.member_id, m.name, b.book_id, b.title, b.category
HAVING SUM(o.quantity) >= 1
ORDER BY 총구매금액 DESC;

INNER JOIN이므로 회원·도서 정보 모두에 일치하는 완료 주문만 집계됩니다. GROUP BY에서 m.member_id와 b.book_id를 포함해 회원-도서 조합별로 집계합니다.

🔗 조인 체인 — 관계 따라가기

이 섹션에서는 테이블 간의 관계를 체계적으로 따라가는 조인 체인 방식을 살펴보겠습니다.

테이블 관계가 A→B→C처럼 연결될 때는 조인을 체인으로 연결합니다. 예를 들어 만약 books 테이블이 publisher_id(출판사)를 외래키로 가진 publisher 테이블이 있다면 다음과 같은 체인 조인이 필요합니다.

-- 체인 조인 패턴 (가상의 publishers 테이블 포함)
-- orders → books → publishers 체인
SELECT
  m.name         AS 회원이름,
  b.title        AS 도서제목,
  -- p.name      AS 출판사     (publishers 테이블이 있다면)
  o.order_date
FROM orders AS o
INNER JOIN members AS m ON o.member_id = m.member_id
INNER JOIN books   AS b ON o.book_id   = b.book_id
-- INNER JOIN publishers AS p ON b.publisher_id = p.publisher_id
ORDER BY o.order_date;

체인 조인의 핵심은 각 JOIN이 이전 결과에 누적된다는 점입니다. FROM orders 시작 → INNER JOIN members 추가 → INNER JOIN books 추가 → (INNER JOIN publishers 추가). 각 단계마다 테이블이 결합되어 최종적으로 하나의 넓은 결과가 만들어집니다.

세 테이블 데이터를 기반으로 실용적인 요약 보고서를 만들어 봅니다. "IT 카테고리 도서를 구매한 VIP 회원 목록"을 구합니다.

SELECT DISTINCT
  m.name    AS 회원이름,
  m.grade   AS 등급
FROM orders AS o
INNER JOIN members AS m ON o.member_id = m.member_id
INNER JOIN books   AS b ON o.book_id   = b.book_id
WHERE m.grade = 'VIP'
  AND b.category = 'IT'
  AND o.status != 'CANCEL';

DISTINCT를 사용해 같은 회원이 IT 도서를 여러 번 주문해도 한 번만 나타나게 합니다. 이처럼 다중 조인과 WHERE, DISTINCT를 조합하면 복잡한 조건의 데이터를 정확히 추출할 수 있습니다.

🪞 셀프 조인 — 같은 테이블을 두 번

이 섹션에서는 하나의 테이블을 자기 자신과 조인하는 셀프 조인(Self Join)의 개념을 살펴보겠습니다.

셀프 조인(Self Join)은 하나의 테이블을 두 번 참조해 같은 테이블 내에서 행끼리 연결하는 기법입니다. 조직도(상위-하위 관계), 친구 관계, "같은 카테고리의 다른 도서"처럼 동일 테이블 내 관계를 표현할 때 사용합니다.

books 테이블에서 같은 카테고리의 다른 도서를 찾는 셀프 조인을 실습합니다.

-- 같은 카테고리의 다른 도서 조합 찾기
SELECT
  a.title    AS 도서A,
  b.title    AS 도서B,
  a.category AS 카테고리
FROM books AS a
INNER JOIN books AS b
       ON  a.category = b.category
       AND a.book_id  < b.book_id   -- 중복 쌍 제거 (A-B와 B-A는 같은 쌍)
ORDER BY a.category, a.book_id;

같은 테이블 books를 a와 b 두 별칭으로 참조합니다. a.book_id < b.book_id 조건은 (도서1, 도서2)와 (도서2, 도서1)처럼 중복 쌍이 생기는 것을 방지합니다. IT 카테고리의 경우 (SQL 첫걸음, 파이썬 독학), (SQL 첫걸음, 클린 코드), (파이썬 독학, 클린 코드) 세 쌍이 나타납니다.

셀프 조인은 처음에는 낯설게 느껴지지만, 같은 테이블을 두 개의 서로 다른 테이블처럼 별칭으로 구분해 사용하는 것뿐입니다. 실무에서는 직원-관리자 관계(employees 테이블에서 manager_id가 같은 테이블의 employee_id를 참조)처럼 계층적 데이터 구조에서 자주 사용됩니다.

⚠️ 다중 조인 주의사항

이 섹션에서는 여러 테이블을 조인할 때 자주 발생하는 문제들을 살펴보겠습니다.

첫 번째 주의사항은 조인 순서에 따른 성능 차이입니다. 논리적 결과는 조인 순서와 무관하지만, 성능은 다를 수 있습니다. 행 수가 많은 테이블을 마지막에 조인하거나, WHERE 조건이 많이 걸리는 테이블을 먼저 조인하면 더 효율적일 수 있습니다. 하지만 현대 DBMS의 쿼리 최적화기가 대부분 자동으로 최적 실행 계획을 선택하므로, 입문 단계에서는 논리적으로 올바른 쿼리를 먼저 작성하는 데 집중합니다.

두 번째는 조인이 많아질수록 결과 행 수가 예상과 달라질 수 있다는 점입니다. 1:N 관계 테이블을 조인하면 N쪽에 행 수만큼 결과가 늘어납니다. 예를 들어 회원 1명이 주문 3건을 가지면 JOIN 후 회원 정보가 3번 반복됩니다. 이를 이해하지 못하면 COUNT(*)나 SUM 결과가 예상보다 많아지는 실수를 합니다. GROUP BY와 COUNT(DISTINCT)로 해결할 수 있습니다.

-- 실수: 회원 수가 주문 수만큼 중복 집계됨
SELECT COUNT(*) AS 회원수
FROM members AS m
INNER JOIN orders AS o ON m.member_id = o.member_id;
-- 결과: 10 (주문 건수) ← 회원 수가 아님!

-- 올바른 방법: DISTINCT로 중복 제거
SELECT COUNT(DISTINCT m.member_id) AS 주문한회원수
FROM members AS m
INNER JOIN orders AS o ON m.member_id = o.member_id;

세 번째는 너무 많은 조인은 가독성을 해친다는 점입니다. 5개 이상의 테이블을 한 쿼리에서 조인하면 이해하기 어렵습니다. 이런 경우 16강에서 배울 서브쿼리나 CTE(Common Table Expressions — WITH 절)로 쿼리를 단계별로 나눠 가독성을 높일 수 있습니다.

📝 핵심 요약

이번 강에서 배운 내용을 정리하겠습니다.

개념핵심 내용
다중 조인 설계중심 테이블(FROM) → 관계 따라 JOIN 추가
INNER + LEFT 혼합각 조인마다 필요에 따라 유형 선택
조인 체인A→B→C 관계를 INNER JOIN 순서로 연결
셀프 조인같은 테이블을 두 별칭으로 참조 — 계층·동질 관계 표현
중복 방지1:N 조인 후 COUNT(DISTINCT)로 정확한 집계

조인을 자유롭게 다룰 수 있게 되면 정규화된 여러 테이블에 분산된 데이터를 원하는 형태로 합칠 수 있습니다. 다음 16강에서는 서브쿼리(Subquery)를 배웁니다. SELECT 안에 또 다른 SELECT를 넣는 서브쿼리는 조인으로 해결하기 어려운 복잡한 조건을 간결하게 표현하는 강력한 도구입니다. "평균 가격보다 비싼 도서", "가장 많이 주문한 회원"처럼 집계 결과를 조건으로 사용하는 쿼리를 배웁니다.

관련 주제

  • 다중 테이블 조인
  • 셀프 조인
  • INNER LEFT JOIN 혼합
  • 조인 설계 전략
  • 개발·프로그래밍
  • 개발·프로그래밍 강의
  • SQL·데이터베이스 입문 24강
  • 무료강의
  • 무료 온라인 강의
  • NUGUNA
  • 누구나

📚 시리즈 전체 공유

SQL·데이터베이스 입문 24강

이 강의가 속한 시리즈는 총 24강, 모두 무료입니다. 처음부터 배우려는 동료에게 시리즈 전체를 알려 주세요.

댓글

0/1000

불러오는 중...