제25장 여러 테이블 JOIN하기
"고객이 주문한 상품은 무엇일까?"
학습 목표
이번 장을 학습하면 다음 내용을 할 수 있습니다.
- 3개 이상의 테이블을 JOIN할 수 있다.
- 여러 단계의 관계를 따라 원하는 정보를 조회할 수 있다.
- 실제 업무에서 사용하는 JOIN 구조를 이해할 수 있다.
- 관계형 데이터베이스의 장점을 이해할 수 있다.
왜 여러 테이블을 JOIN해야 할까요?
지난 시간에는 Customers와 Orders처럼 두 개의 테이블을 연결했습니다.
하지만 실제 회사에서는 원하는 정보가 하나의 테이블에만 저장되어 있는 경우가 거의 없습니다.
예를 들어 다음과 같은 질문을 생각해 봅시다.
"홍길동 고객이 주문한 상품 이름은 무엇인가?"
이 질문에 답하려면 어느 테이블을 봐야 할까요?
Customers에는 고객 이름이 있습니다.
Orders에는 주문번호가 있습니다.
OrderDetails에는 주문한 상품 번호가 있습니다.
Products에는 상품 이름이 있습니다.
즉,
고객 → 주문 → 주문상세 → 상품
을 차례대로 따라가야 합니다.
관계를 다시 살펴보기
Customers
│
│ CustomerID
▼
Orders
│
│ OrderID
▼
OrderDetails
│
│ ProductID
▼
Products
이처럼 데이터는 서로 연결되어 있습니다.
JOIN은 이 연결을 따라가는 작업입니다.
실행 결과 먼저 보기
다음과 같은 결과를 얻고 싶다고 가정해 보겠습니다.
| 고객명 | 주문일 | 상품명 |
| Alfreds Futterkiste | 1996-07-04 | Chai |
| Alfreds Futterkiste | 1996-07-04 | Chang |
| Around the Horn | 1996-07-05 | Ikura |
| Berglunds snabbköp | 1996-07-08 | Queso Cabrales |
한 번의 SQL로 이러한 결과를 만들 수 있습니다.
예제 1. 고객이 주문한 상품 조회하기
SELECT Customers.CustomerName,
Orders.OrderDate,
Products.ProductName
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
INNER JOIN Products
ON OrderDetails.ProductID = Products.ProductID;
SQL를 한 줄씩 살펴보기
SELECT Customers.CustomerName,
고객 이름을 가져옵니다.
Orders.OrderDate,
주문 날짜를 가져옵니다.
Products.ProductName
상품 이름을 가져옵니다.
FROM Customers
Customers 테이블에서 시작합니다.
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
고객과 주문을 연결합니다.
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
주문과 주문상세를 연결합니다.
INNER JOIN Products
ON OrderDetails.ProductID = Products.ProductID
상품 번호를 이용하여 상품 이름을 가져옵니다.
JOIN의 흐름 이해하기
SQL은 아래와 같은 순서로 데이터를 찾습니다.
① 고객 찾기
Customers
↓
② 고객의 주문 찾기
Orders
↓
③ 주문에 포함된 상품번호 찾기
OrderDetails
↓
④ 상품번호로 상품 이름 찾기
Products
관계를 하나씩 따라가기 때문에 원하는 정보를 얻을 수 있습니다.
실제 업무에서는?
온라인 쇼핑몰에서
"고객이 어떤 상품을 구매했는가"
를 조회하는 가장 기본적인 형태입니다.
관리자는
- 구매 내역 조회
- 영수증 출력
- 주문 내역 확인
- 배송 준비
등 대부분의 업무에서 이러한 JOIN을 사용합니다.
예제 2. 주문번호도 함께 출력하기
SELECT Orders.OrderID,
Customers.CustomerName,
Products.ProductName
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
INNER JOIN Products
ON OrderDetails.ProductID = Products.ProductID;
실행하면
| 주문번호 | 고객명 | 상품명 |
| 10248 | Alfreds Futterkiste | Chai |
| 10248 | Alfreds Futterkiste | Chang |
| 10249 | Around the Horn | Ikura |
처럼 하나의 주문에 여러 상품이 표시됩니다.
왜 같은 주문번호가 여러 번 나타날까요?
가장 많이 하는 질문입니다.
예를 들어 주문번호 10248에
- Chai
- Chang
두 상품을 주문했다면
OrderDetails에는 두 개의 행이 저장됩니다.
따라서 결과도 두 줄이 출력됩니다.
주문 10248
├── Chai
└── Chang
이는 정상적인 결과입니다.
많이 하는 실수
실수 ①
Customers와 Products를 직접 연결하려고 한다.
Customers.CustomerID = Products.ProductID
❌ 두 테이블은 직접 연결되지 않습니다.
항상 관계를 따라가야 합니다.
실수 ②
JOIN 순서를 무시한다.
Customers
↓
Products
처럼 바로 연결할 수는 없습니다.
반드시
Customers
↓
Orders
↓
OrderDetails
↓
Products
순서대로 연결해야 합니다.
실수 ③
ON 절을 하나 빼먹는다.
INNER JOIN Products
까지만 작성하면 오류가 발생합니다.
JOIN에는 반드시 ON이 필요합니다.
한눈에 정리
Customers
↓
Orders
↓
OrderDetails
↓
Products
관계를 따라가면
"고객이 주문한 상품"
을 조회할 수 있습니다.
이번 장 핵심 정리
✅ 여러 개의 테이블도 JOIN할 수 있다.
✅ 관계를 하나씩 따라가면 된다.
✅ 원하는 정보는 여러 테이블에 나누어 저장된다.
✅ 실제 업무에서는 3~6개의 테이블을 JOIN하는 경우도 매우 많다.
연습 문제
기본 문제
① 고객 이름과 주문 날짜를 조회하시오.
② 고객 이름과 상품 이름을 조회하시오.
응용 문제
① 주문번호, 고객 이름, 주문 날짜, 상품 이름을 출력하시오.
② 상품 이름만 출력하지 말고 주문번호도 함께 출력하시오.
도전 문제
다음과 같은 결과가 출력되도록 SQL을 작성해 보시오.
| 고객명 | 주문번호 | 주문일 | 상품명 |
정답
기본 ①
SELECT Customers.CustomerName,
Orders.OrderDate
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID;
기본 ②
SELECT Customers.CustomerName,
Products.ProductName
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
INNER JOIN Products
ON OrderDetails.ProductID = Products.ProductID;
응용 및 도전
SELECT Customers.CustomerName,
Orders.OrderID,
Orders.OrderDate,
Products.ProductName
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
INNER JOIN Products
ON OrderDetails.ProductID = Products.ProductID;
'프로그래밍 > MySQL' 카테고리의 다른 글
| 📊 [SQL 프로젝트] 제27장 RIGHT JOIN - 오른쪽 테이블을 기준으로 보고 싶다면? (0) | 2026.07.07 |
|---|---|
| 📊 [SQL 프로젝트] 제26장 LEFT JOIN - 주문하지 않은 고객도 보고 싶습니다. (0) | 2026.07.07 |
| 📊 [SQL 프로젝트] 제24장 관계를 따라 JOIN하기 - 데이터베이스 지도를 읽는 방법 (0) | 2026.07.06 |
| 📊 [SQL 프로젝트] 제23장 INNER JOIN - 두 테이블을 연결해 봅시다. (0) | 2026.07.06 |
| 📊 [SQL 프로젝트] 제22장 왜 JOIN이 필요할까요? - 여러 테이블을 연결하는 이유 (0) | 2026.07.06 |