표준 조인, INNER·OUTER·CROSS JOIN
목차
SQLD 2과목의 「표준 조인」 항목을 정리합니다. FROM 절에 JOIN 키워드로 조인을 쓰는 표준 조인 문법, INNER JOIN과 ON 절, USING과 NATURAL JOIN의 규칙, CROSS JOIN, LEFT·RIGHT·FULL OUTER JOIN의 결과와 행 수 계산, OUTER JOIN에서 조건을 ON에 둘 때와 WHERE에 둘 때의 차이, 여러 테이블 OUTER JOIN, 오라클 (+) 표기를 표준 조인으로 바꿔 쓰는 방법, SQL Server와의 차이를 쇼핑몰 예시로 살펴본 뒤 기출 유형 연습 문제 5개로 확인합니다.
앞 글 「조인 기초, 등가 조인과 오라클 (+) 표기」에서 WHERE 절에 조인 조건을 쓰는 방식과 오라클 (+) 아우터 조인을 정리했습니다. 이번에는 같은 조인을 FROM 절에 JOIN 키워드로 쓰는 표준 조인(ANSI/ISO SQL 표준)을 다룹니다. 시험에는 표준 조인의 결과 행 수를 세는 문제, NATURAL JOIN과 USING의 문법 오류를 고르는 문제, (+) 표기와 같은 결과를 내는 표준 조인을 고르는 문제가 자주 나옵니다. 예시 데이터는 앞 글과 같은 쇼핑몰 다섯 테이블과 가격대, 쿠폰 테이블입니다. 연습 문제는 실제 시험과 같은 유형으로 새로 만든 문제입니다.
1. 표준 조인 한눈에 보기

표준 조인은 조인 종류와 조인 조건을 FROM 절에 씁니다.
SELECT ... FROM A [INNER] JOIN B ON 조인조건;
SELECT ... FROM A JOIN B USING (같은이름컬럼);
SELECT ... FROM A NATURAL JOIN B;
SELECT ... FROM A CROSS JOIN B;
SELECT ... FROM A LEFT [OUTER] JOIN B ON 조인조건;
SELECT ... FROM A RIGHT [OUTER] JOIN B ON 조인조건;
SELECT ... FROM A FULL [OUTER] JOIN B ON 조인조건;
| 종류 | 결과 | 쇼핑몰 예 |
|---|---|---|
| INNER JOIN | 양쪽에 짝이 있는 행만 | 고객-주문 7행 |
| USING | 지정한 같은 이름 컬럼으로 등가 조인 | 고객-주문 7행 |
| NATURAL JOIN | 이름이 같은 모든 컬럼으로 등가 조인 | 고객-주문 7행 |
| CROSS JOIN | 카티션 곱(조건 없음) | 등급 3 × 가격대 4 = 12행 |
| LEFT OUTER JOIN | 왼쪽 전부, 짝이 없으면 오른쪽은 NULL | 고객-주문 8행(C05는 NULL) |
| RIGHT OUTER JOIN | 오른쪽 전부, 짝이 없으면 왼쪽은 NULL | 주문상품-상품 12행(P40은 NULL) |
| FULL OUTER JOIN | 양쪽 전부, 짝이 없으면 반대쪽은 NULL | 고객-쿠폰 6행 |
- INNER와 OUTER는 생략할 수 있습니다.
JOIN만 쓰면 INNER JOIN,LEFT JOIN은 LEFT OUTER JOIN,FULL JOIN은 FULL OUTER JOIN입니다. - 표준 조인은 조인 조건은 FROM 절(ON, USING)에, 행을 거르는 조건은 WHERE 절에 두어 둘을 나눠 볼 수 있다는 것이 장점입니다.
2. INNER JOIN과 ON

앞 글에서 WHERE 절로 쓴 주문-고객-등급 조인을 INNER JOIN으로 바꾸면 다음과 같습니다.
SELECT o.주문번호, c.고객명, g.등급명
FROM 주문 o
INNER JOIN 고객 c ON o.고객번호 = c.고객번호
INNER JOIN 등급 g ON c.등급코드 = g.등급코드
WHERE g.등급코드 = 'G'
ORDER BY o.주문번호;
| 주문번호 | 고객명 | 등급명 |
|---|---|---|
| 5001 | 김하나 | 골드 |
| 5003 | 김하나 | 골드 |
| 5006 | 최네오 | 골드 |
- ON에는
=뿐 아니라 비등가 조건도 쓸 수 있습니다.상품 p JOIN 가격대 g ON p.판매가 BETWEEN g.최저가 AND g.최고가는 앞 글과 같은 6행입니다. - INNER JOIN에서 ON(또는 USING)을 빼면 오류입니다.
FROM 고객 c INNER JOIN 주문 o만 쓰면 ORA-02000(ON 또는 USING 키워드 누락)입니다. - INNER JOIN에서는 일반 조건(
c.등급코드 = 'G')을 ON에 두든 WHERE에 두든 결과가 같습니다(둘 다 3행). OUTER JOIN에서는 달라지는데, 6장에서 봅니다.
3. USING과 NATURAL JOIN

USING과 NATURAL JOIN은 이름이 같은 컬럼으로 등가 조인합니다. USING은 괄호 안에 조인할 컬럼을 직접 적고, NATURAL JOIN은 두 테이블에서 이름이 같은 모든 컬럼을 알아서 찾습니다.
SELECT 고객번호, c.고객명, o.주문번호
FROM 고객 c JOIN 주문 o USING (고객번호);
SELECT 고객번호, c.고객명, o.주문번호
FROM 고객 c NATURAL JOIN 주문 o;
두 SQL 모두 고객-주문 7행입니다. 고객과 주문에 같은 이름의 컬럼은 고객번호 하나뿐이라 결과가 같습니다.
| 항목 | USING | NATURAL JOIN |
|---|---|---|
| 조인 컬럼 | 괄호 안에 지정한 컬럼 | 이름이 같은 모든 컬럼 |
| 조건 종류 | 등가 조인만 | 등가 조인만 |
| 조인 컬럼에 별칭·테이블명 | 불가(ORA-25154) | 불가(ORA-25155) |
| 조인 컬럼이 아닌 컬럼 | 별칭 사용 가능 | 별칭 사용 가능 |
| ON과 함께 쓰기 | 불가 | 불가(ORA-03048) |
| SELECT *의 공통 컬럼 | 맨 앞에 한 번만 | 맨 앞에 한 번만 |
| SQL Server | 지원 안 함 | 지원 안 함 |
가장 자주 나오는 것은 셋째 줄입니다. USING이나 NATURAL JOIN에 쓰인 조인 컬럼은 어느 한 테이블의 것이 아니라 두 테이블이 함께 쓰는 컬럼이 되므로 접두사를 붙일 수 없습니다.
-- 오류(ORA-25154): USING 조인 컬럼에 별칭을 붙임
SELECT c.고객번호, c.고객명
FROM 고객 c JOIN 주문 o USING (고객번호);
SELECT *의 컬럼 순서
SELECT * FROM 등급 g JOIN 고객 c USING (등급코드);
SELECT * FROM 등급 NATURAL JOIN 고객;
SELECT * FROM 등급 g JOIN 고객 c ON g.등급코드 = c.등급코드;
| 조인 | 결과 컬럼 |
|---|---|
| USING | 등급코드, 등급명, 할인율, 고객번호, 고객명, 휴대폰번호, 이메일 |
| NATURAL JOIN | 등급코드, 등급명, 할인율, 고객번호, 고객명, 휴대폰번호, 이메일 |
| ON | 등급코드, 등급명, 할인율, 고객번호, 고객명, 휴대폰번호, 이메일, 등급코드 |
- 고객 테이블의 마지막 컬럼이던 등급코드가 USING과 NATURAL JOIN에서는 맨 앞으로 와서 한 번만 나옵니다. ON은 두 테이블의 컬럼을 모두 보여 주므로 등급코드가 두 번 나옵니다.
- 같은 이름의 컬럼이 하나도 없는
상품 NATURAL JOIN 등급은 오류가 아니라 6 × 3 = 18행, 즉 카티션 곱이 됩니다. - 같은 이름의 컬럼이 둘 이상이면(예: 두 테이블 모두에 「등록일」이 있는 경우) NATURAL JOIN은 의도하지 않은 컬럼까지 조건에 넣습니다. 그래서 실무에서는 조인 컬럼을 직접 적는 ON이나 USING을 더 많이 씁니다.
4. CROSS JOIN

SELECT g.등급명, p.가격대명
FROM 등급 g CROSS JOIN 가격대 p;
- 등급 3행 × 가격대 4행 = 12행입니다. 「등급별·가격대별 판매 실적표의 빈칸까지 모두 만들기」처럼 모든 조합이 필요할 때 씁니다.
FROM 등급 g, 가격대 p처럼 조건 없이 쉼표로 나열한 것과 같습니다.- CROSS JOIN에는 ON을 붙일 수 없습니다(ORA-03048).
5. OUTER JOIN 세 가지와 행 수

고객(5행)과 쿠폰(3행, K03은 고객번호 NULL)을 c.고객번호 = k.고객번호로 이어 보겠습니다.
SELECT c.고객번호, c.고객명, k.쿠폰번호, k.쿠폰명
FROM 고객 c FULL OUTER JOIN 쿠폰 k
ON c.고객번호 = k.고객번호
ORDER BY c.고객번호, k.쿠폰번호;
| 고객번호 | 고객명 | 쿠폰번호 | 쿠폰명 |
|---|---|---|---|
| C01 | 김하나 | K01 | 여름_10%할인 |
| C02 | 이두리 | NULL | NULL |
| C03 | 박세미 | K02 | 여름10할인 |
| C04 | 최네오 | NULL | NULL |
| C05 | 정다솜 | NULL | NULL |
| NULL | NULL | K03 | 가을_5%할인 |
FULL 자리에 다른 조인을 넣으면 행 수가 다음과 같습니다.
| 조인 | 행 수 | 결과 |
|---|---|---|
| INNER | 2 | C01-K01, C03-K02 |
| LEFT(고객 기준) | 5 | 위 2행 + C02, C04, C05(쿠폰 NULL) |
| RIGHT(쿠폰 기준) | 3 | 위 2행 + K03(고객 NULL) |
| FULL | 6 | 위 2행 + C02, C04, C05 + K03 |
| CROSS | 15 | 5 × 3 |
- FULL OUTER JOIN은 LEFT와 RIGHT 결과의 합집합(UNION)입니다. LEFT 5행과 RIGHT 3행에서 겹치는 2행이 한 번만 남아 6행입니다. 행 수는 LEFT + RIGHT - INNER = 5 + 3 - 2 = 6이고, 단순히 더한 8이 아닙니다.
A LEFT JOIN B와B RIGHT JOIN A는 같습니다.고객 LEFT JOIN 주문과주문 RIGHT JOIN 고객은 둘 다 8행입니다.- K03은 고객번호가 NULL이라 어떤 고객과도 짝이 되지 않습니다. 그래서 쿠폰을 모두 남기는 RIGHT와 FULL에서만 보입니다.
6. OUTER JOIN에서 ON 조건과 WHERE 조건

INNER JOIN에서는 같았던 ON과 WHERE가 OUTER JOIN에서는 결과를 바꿉니다.
-- (가) 날짜 조건을 ON에
SELECT c.고객번호, o.주문번호
FROM 고객 c LEFT OUTER JOIN 주문 o
ON c.고객번호 = o.고객번호
AND o.주문일시 >= DATE '2026-10-05';
-- (나) 날짜 조건을 WHERE에
SELECT c.고객번호, o.주문번호
FROM 고객 c LEFT OUTER JOIN 주문 o
ON c.고객번호 = o.고객번호
WHERE o.주문일시 >= DATE '2026-10-05';
| 조건 위치 | 결과 |
|---|---|
| (가) 오른쪽 테이블 조건을 ON에 | 5행: C01 NULL, C02 5005, C03 5007, C04 5006, C05 NULL |
| (나) 오른쪽 테이블 조건을 WHERE에 | 3행: C02 5005, C03 5007, C04 5006 |
(다) 왼쪽 테이블 조건 c.등급코드 = 'G'를 ON에 |
6행: C01(5001, 5003)과 C04(5006)만 주문이 붙고, C02·C03·C05는 주문 NULL로 남음 |
(라) 왼쪽 테이블 조건 c.등급코드 = 'G'를 WHERE에 |
3행: 5001, 5003, 5006 |
- ON 조건은 「어떤 행끼리 짝을 지을지」만 정합니다. LEFT JOIN의 왼쪽 행은 ON 조건이 거짓이어도 사라지지 않고, 짝이 없는 행으로 남습니다. 그래서 (다)는 고객 5명이 모두 남습니다.
- WHERE 조건은 조인이 끝난 결과를 거릅니다. (나)에서 NULL로 채운 C01, C05 행은
o.주문일시 >= …에서 UNKNOWN이 되어 빠지므로 결과적으로 INNER JOIN과 같아집니다. - 앞 글의 「상수 조건에 (+)가 없음」과 같은 현상입니다. 날짜 조건을 ON에 넣은 (가)가 「상수 조건에도 (+)」를 붙인 SQL과 같은 결과(5행)입니다.
7. 여러 테이블 OUTER JOIN

고객 전부와 주문, 주문상품을 이어 보겠습니다.
-- (가) 두 번째 조인도 LEFT: 12행, 마지막 행이 C05 NULL NULL
SELECT c.고객번호, o.주문번호, oi.상품번호
FROM 고객 c
LEFT JOIN 주문 o ON c.고객번호 = o.고객번호
LEFT JOIN 주문상품 oi ON o.주문번호 = oi.주문번호;
-- (나) 두 번째 조인이 INNER: 11행, C05가 사라짐
SELECT c.고객번호, o.주문번호, oi.상품번호
FROM 고객 c
LEFT JOIN 주문 o ON c.고객번호 = o.고객번호
JOIN 주문상품 oi ON o.주문번호 = oi.주문번호;
(나)에서는 앞의 LEFT JOIN으로 살린 C05 행의 주문번호가 NULL이라, 뒤의 INNER JOIN 조건 o.주문번호 = oi.주문번호에서 짝을 찾지 못해 빠집니다. 앞 글에서 본 「(+)를 일부 조건에 빠뜨림」(11행)과 같습니다. 살린 행을 끝까지 남기려면 이어지는 조인도 LEFT로 씁니다.
짝이 없는 행만 찾기
SELECT c.고객번호, c.고객명
FROM 고객 c LEFT JOIN 주문 o
ON c.고객번호 = o.고객번호
WHERE o.주문번호 IS NULL;
결과는 C05 정다솜 1행입니다. 「주문이 없는 고객」은 뒤의 글에서 NOT EXISTS와 MINUS로도 같은 답을 구해 봅니다.
8. (+) 표기를 표준 조인으로 바꾸기

-- 오라클 (+) 표기: 8행
SELECT c.고객번호, o.주문번호
FROM 고객 c, 주문 o
WHERE c.고객번호 = o.고객번호(+);
-- 표준 조인: 같은 8행
SELECT c.고객번호, o.주문번호
FROM 고객 c LEFT OUTER JOIN 주문 o
ON c.고객번호 = o.고객번호;
| (+) 표기 | 표준 조인과 결과 |
|---|---|
주문 쪽에 (+), o.고객번호(+) |
고객 LEFT JOIN 주문, 8행 |
고객 쪽에 (+), c.고객번호(+) |
고객 RIGHT JOIN 주문, 7행 |
주문상품 쪽에 (+), oi.상품번호(+) |
주문상품 RIGHT JOIN 상품, 12행 |
| 상수 조건에도 (+) | 상수 조건을 ON으로, 5행 |
| 상수 조건에 (+) 없음 | 상수 조건을 WHERE로, 3행 |
| 양쪽에 (+)는 불가 | FULL OUTER JOIN, 고객-쿠폰 6행 |
바꿔 쓰는 요령은 다음과 같습니다.
- (+)가 없는 쪽이 기준, 즉 모두 남는 쪽입니다. FROM 절에서 기준 테이블을 왼쪽에 두면 LEFT, 오른쪽에 두면 RIGHT입니다.
FROM 주문상품 oi, 상품 p WHERE oi.상품번호(+) = p.상품번호는 상품이 기준이고 상품이 FROM 절 오른쪽에 있으므로 RIGHT OUTER JOIN입니다. LEFT로 바꾸면 주문상품 기준이 되어 11행입니다.- (+)가 붙은 상수 조건은 ON으로, (+)가 없는 조건은 WHERE로 옮깁니다.
- NATURAL LEFT JOIN도 쓸 수 있지만(
고객 NATURAL LEFT JOIN 주문은 8행) 시험에는 거의 나오지 않습니다.
9. SQL Server와의 차이

| 항목 | 오라클 | SQL Server |
|---|---|---|
| INNER, LEFT, RIGHT, FULL, CROSS | 지원 | 지원(결과 같음) |
| NATURAL JOIN | 지원 | 문법 오류 |
| USING | 지원 | 문법 오류 |
| (+) | 지원 | 문법 오류 |
| 오름차순 정렬에서 NULL | 맨 뒤 | 맨 앞 |
- SQL Server의 FROM 절 조인은 INNER, LEFT·RIGHT·FULL OUTER, CROSS JOIN이고 NATURAL JOIN과 USING이 없습니다. 「SQL Server는 NATURAL JOIN과 USING을 지원하지 않는다」는 보기가 자주 나옵니다.
- FULL OUTER JOIN 결과를 ORDER BY로 정렬하면 NULL의 위치가 다릅니다. 「WHERE 절과 ORDER BY, Top N 쿼리」에서 본 NULL 정렬 차이와 같습니다.
10. 헷갈리기 쉬운 점

- USING과 NATURAL JOIN의 조인 컬럼에는 접두사를 붙이지 않습니다.
c.고객번호가 아니라고객번호라고 씁니다. 조인 컬럼이 아닌 컬럼(c.고객명)에는 붙여도 됩니다. - NATURAL JOIN은 이름이 같은 「모든」 컬럼으로 조인합니다. 같은 이름의 컬럼이 없으면 오류가 아니라 카티션 곱입니다.
- FULL OUTER JOIN의 행 수는 LEFT + RIGHT가 아닙니다. 양쪽 모두에 짝이 있는 행(INNER 결과)이 두 번 세어지므로 한 번 빼야 합니다. FULL은 LEFT와 RIGHT를 UNION ALL이 아니라 UNION한 것과 같습니다.
- OUTER JOIN에서 ON과 WHERE는 다릅니다. 오른쪽 테이블 조건을 WHERE에 두면 NULL 행이 걸러져 INNER JOIN처럼 되고, 왼쪽 테이블 조건을 ON에 두면 왼쪽 행은 줄지 않습니다.
- LEFT JOIN 다음의 INNER JOIN은 살린 행을 다시 지울 수 있습니다. 이어지는 조인도 LEFT로 써야 C05 같은 행이 남습니다.
- (+)를 표준 조인으로 바꿀 때는 (+)가 없는 테이블이 기준입니다. 기준 테이블이 왼쪽이면 LEFT, 오른쪽이면 RIGHT입니다.
- INNER JOIN에는 ON이나 USING이 꼭 필요하고, CROSS JOIN과 NATURAL JOIN에는 ON을 쓸 수 없습니다.
- 조인 컬럼이 NULL인 행은 INNER JOIN에서 빠지고 OUTER JOIN에서만 남습니다. 쿠폰 K03은 RIGHT와 FULL에서만 보입니다.
11. 연습 문제

표준 조인의 결과 행 수와 문법 규칙, (+) 표기와의 관계를 확인하는 문제입니다. 실제 시험과 같은 유형으로 새로 만들었습니다. 정답과 풀이는 다음 장에 있으니, 먼저 직접 풀어 보세요.
문제 1에서 쓰는 두 테이블은 다음과 같습니다.
[고객]
| 고객번호 | 고객명 |
|---|---|
| C01 | 김하나 |
| C02 | 이두리 |
| C03 | 박세미 |
| C04 | 최네오 |
| C05 | 정다솜 |
[쿠폰]
| 쿠폰번호 | 고객번호 |
|---|---|
| K01 | C01 |
| K02 | C03 |
| K03 | NULL |
문제 1. 다음 네 SQL의 결과 행 수를 (가)부터 차례대로 바르게 나열한 것은?
(가) SELECT * FROM 고객 c INNER JOIN 쿠폰 k ON c.고객번호 = k.고객번호;
(나) SELECT * FROM 고객 c LEFT OUTER JOIN 쿠폰 k ON c.고객번호 = k.고객번호;
(다) SELECT * FROM 고객 c RIGHT OUTER JOIN 쿠폰 k ON c.고객번호 = k.고객번호;
(라) SELECT * FROM 고객 c FULL OUTER JOIN 쿠폰 k ON c.고객번호 = k.고객번호;
① 2, 5, 3, 8
② 3, 5, 3, 6
③ 2, 5, 2, 5
④ 2, 5, 3, 6
문제 2. 주문 테이블에도 고객번호 컬럼이 있다. 오라클 기준으로 오류가 발생하는 SQL은?
① SELECT 고객번호, c.고객명 FROM 고객 c JOIN 주문 o USING (고객번호);
② SELECT 고객번호, o.주문번호 FROM 고객 c NATURAL JOIN 주문 o;
③ SELECT c.고객번호, c.고객명 FROM 고객 c JOIN 주문 o USING (고객번호);
④ SELECT c.고객번호, o.주문번호 FROM 고객 c JOIN 주문 o ON c.고객번호 = o.고객번호;
문제 3. [주문] 테이블이 다음과 같고, 고객 테이블에는 C01~C05 다섯 명이 있다. 두 SQL의 결과 행 수를 차례대로 고른 것은?
| 주문번호 | 고객번호 | 주문일시 |
|---|---|---|
| 5001 | C01 | 2026-10-01 |
| 5002 | C02 | 2026-10-02 |
| 5003 | C01 | 2026-10-03 |
| 5004 | C03 | 2026-10-04 |
| 5005 | C02 | 2026-10-05 |
| 5006 | C04 | 2026-10-06 |
| 5007 | C03 | 2026-10-07 |
(가) SELECT c.고객번호, o.주문번호
FROM 고객 c LEFT OUTER JOIN 주문 o
ON c.고객번호 = o.고객번호 AND o.주문일시 >= DATE '2026-10-05';
(나) SELECT c.고객번호, o.주문번호
FROM 고객 c LEFT OUTER JOIN 주문 o
ON c.고객번호 = o.고객번호
WHERE o.주문일시 >= DATE '2026-10-05';
① 5, 3
② 5, 5
③ 3, 3
④ 8, 3
문제 4. 다음 오라클 SQL과 결과가 같은 SQL은? (상품은 6개이고, 그중 P40은 주문상품에 한 번도 나오지 않는다.)
SELECT p.상품번호, oi.주문번호
FROM 주문상품 oi, 상품 p
WHERE oi.상품번호(+) = p.상품번호;
① SELECT p.상품번호, oi.주문번호 FROM 주문상품 oi LEFT OUTER JOIN 상품 p ON oi.상품번호 = p.상품번호;
② SELECT p.상품번호, oi.주문번호 FROM 주문상품 oi RIGHT OUTER JOIN 상품 p ON oi.상품번호 = p.상품번호;
③ SELECT p.상품번호, oi.주문번호 FROM 주문상품 oi INNER JOIN 상품 p ON oi.상품번호 = p.상품번호;
④ SELECT p.상품번호, oi.주문번호 FROM 주문상품 oi FULL OUTER JOIN 상품 p ON oi.상품번호(+) = p.상품번호;
문제 5. 표준 조인에 대한 설명으로 가장 적절하지 않은 것은?
① NATURAL JOIN은 두 테이블에서 이름이 같은 모든 컬럼으로 등가 조인한다.
② CROSS JOIN은 조인 조건 없이 두 테이블의 모든 행을 조합한다.
③ FULL OUTER JOIN의 결과 행 수는 항상 LEFT OUTER JOIN 행 수와 RIGHT OUTER JOIN 행 수를 더한 값이다.
④ SQL Server는 USING 절을 지원하지 않는다.
12. 풀이
문제 1. 정답 ④
INNER는 짝이 있는 C01-K01, C03-K02의 2행입니다. LEFT는 고객 5명 전부라 5행, RIGHT는 쿠폰 3장 전부라 3행입니다(K03은 고객번호가 NULL이라 짝이 없음). FULL은 LEFT + RIGHT - INNER = 5 + 3 - 2 = 6행입니다. ①은 FULL을 단순히 더한 값, ③은 K03을 빠뜨린 값입니다.
문제 2. 정답 ③
USING에 쓴 조인 컬럼(고객번호)에는 테이블 별칭을 붙일 수 없습니다(ORA-25154). ①은 조인 컬럼에 접두사가 없고 다른 컬럼에만 붙였으므로 실행됩니다. ②도 NATURAL JOIN의 공통 컬럼에 접두사가 없어 실행되고(7행), ④는 ON이라 오히려 접두사가 필요합니다.
문제 3. 정답 ①
(가)는 날짜 조건이 ON에 있어 「짝 짓기 조건」으로만 쓰이므로 고객 5명이 모두 남습니다(C01, C05는 주문 NULL). (나)는 조인 뒤 WHERE에서 NULL 행과 10월 5일 이전 주문이 걸러져 5005, 5006, 5007의 3행만 남습니다. ④의 8은 날짜 조건이 없을 때의 LEFT JOIN 행 수입니다.
문제 4. 정답 ②
(+)가 주문상품 쪽에 있으므로 주문상품이 NULL로 채워지는 쪽이고, 상품이 모두 남습니다. FROM 절 오른쪽에 있는 상품을 모두 남기는 RIGHT OUTER JOIN입니다(12행, P40은 주문번호 NULL). ①은 주문상품 기준이라 11행, ③도 11행이고, ④는 표준 조인 안에 (+)를 섞어 오류(ORA-25156)입니다.
문제 5. 정답 ③
FULL OUTER JOIN의 행 수는 LEFT + RIGHT - INNER입니다. 문제 1처럼 5 + 3 = 8이 아니라 6입니다.
마치며
이번 글에서는 FROM 절에 쓰는 표준 조인을 정리했습니다.
- INNER JOIN은 ON(또는 USING)이 꼭 필요하고, INNER와 OUTER는 생략할 수 있습니다.
- USING과 NATURAL JOIN은 같은 이름 컬럼으로 등가 조인하며, 조인 컬럼에는 별칭을 붙일 수 없습니다. SELECT *에서 공통 컬럼은 맨 앞에 한 번만 나옵니다.
- 같은 이름 컬럼이 없는 NATURAL JOIN과 CROSS JOIN은 카티션 곱입니다. 예시에서 등급 × 가격대는 12행입니다.
- 고객-쿠폰 예시에서 INNER 2, LEFT 5, RIGHT 3, FULL 6, CROSS 15행입니다. FULL은 LEFT + RIGHT - INNER입니다.
- OUTER JOIN에서 오른쪽 테이블 조건을 WHERE에 두면 INNER JOIN처럼 되고, ON에 두면 왼쪽 행이 모두 남습니다.
- (+) 표기를 바꿀 때는 (+)가 없는 테이블이 기준입니다. SQL Server는 NATURAL JOIN, USING, (+)를 지원하지 않습니다.
다음 글 「서브쿼리 종류와 NOT IN의 NULL 함정」에서는 SQL 안에 SQL을 넣는 서브쿼리를 다룹니다. 스칼라 서브쿼리와 인라인 뷰, 단일행·다중행 서브쿼리와 ANY·ALL·EXISTS, NOT IN과 NULL의 함정, 연관 서브쿼리와 뷰를 쇼핑몰 예시로 살펴보고 기출 유형 문제로 확인합니다.
참고 자료(공식)
'DB' 카테고리의 다른 글
| 집합 연산자와 ROLLUP·CUBE·GROUPING SETS (0) | 2026.10.08 |
|---|---|
| 서브쿼리 종류와 NOT IN의 NULL 함정 (0) | 2026.10.08 |
| 조인 기초, 등가 조인과 오라클 (+) 표기 (0) | 2026.10.08 |
| GROUP BY와 HAVING, 집계 함수와 NULL (0) | 2026.10.08 |
| WHERE 절과 ORDER BY, Top N 쿼리 (0) | 2026.10.08 |