Search
moon
sun

14.조인 ② (OUTER JOIN과 표준 조인)

•
OUTER JOIN으로 짝이 없는 행도 결과에 포함시킬 수 있다.
•
Oracle (+) 문법과 ANSI LEFT/RIGHT/FULL OUTER JOIN을 서로 변환할 수 있다.
•
ON · USING · NATURAL JOIN · CROSS JOIN 표준 조인을 구분해 쓸 수 있다.
•
OUTER JOIN에서 ON과 WHERE의 위치가 결과를 바꾼다는 것을 안다.

1. OUTER JOIN이 왜 필요한가

1) 13강의 누락 문제를 다시 보기

구분
INNER JOIN
OUTER JOIN
결과
양쪽 다 매칭되는 행만
한쪽에만 있어도 살림
짝 없는 행
제외
NULL로 채워 표시
05강 관점
필수 관계면 충분
선택적 관계에 필요

2) 집합으로 보는 조인

2. Oracle (+) 문법 ⭐⭐

1) (+) 는 "데이터가 부족한 쪽"에 붙인다

짝이 없어서 NULL이 채워질 쪽에 (+) 를 붙인다.
-- ============================================================ -- 【시험용 예제】 사원이 없는 40번 부서까지 모두 보기 ★★ -- ============================================================ -- ❌ INNER JOIN : 40번 부서 누락 (13강) SELECT D.DEPTNO, D.DNAME, E.ENAME FROM DEPT D, EMP E WHERE D.DEPTNO = E.DEPTNO; -- → 14건, 40번(OPERATIONS) 없음 -- ✅ OUTER JOIN : DEPT 를 전부 보존 SELECT D.DEPTNO, D.DNAME, E.ENAME FROM DEPT D, EMP E WHERE D.DEPTNO = E.DEPTNO(+); -- 부족한 쪽(EMP)에 (+) 를 붙인다 -- DEPTNO DNAME ENAME -- ------ ---------- ------ -- 10 ACCOUNTING CLARK -- 10 ACCOUNTING KING -- ... -- 30 SALES JAMES -- 40 OPERATIONS (NULL) ← 사원이 없어도 부서는 나온다! ✅ -- → 15건 (14 + 40번 부서 1건) -- -- ⭐ 핵심 : DEPT 는 전부 보이고 싶고, 짝이 없어 NULL 이 채워질 곳은 EMP 쪽이다. -- → EMP 쪽 조인 컬럼에 (+) 를 붙인다. "부족한 쪽에 (+)"
SQL
복사

2) (+) 위치 규칙

⚠️ 최다 함정: (+) 는 기준이 되는 쪽이 아니라, NULL로 채워질 쪽에 붙입니다. "DEPT를 다 보고 싶으면 DEPT에 붙인다"고 생각하면 반대입니다. EMP(부족한 쪽)에 붙입니다.

3. ANSI OUTER JOIN ⭐⭐⭐

1) LEFT / RIGHT / FULL

-- ============================================================ -- 【이해용 예제】 위와 같은 결과를 ANSI 문법으로 -- ============================================================ -- LEFT OUTER JOIN : 왼쪽 테이블(DEPT)을 전부 보존 SELECT D.DEPTNO, D.DNAME, E.ENAME FROM DEPT D LEFT OUTER JOIN EMP E -- OUTER 는 생략 가능 (LEFT JOIN) ON D.DEPTNO = E.DEPTNO; -- → 15건, 40번 부서 포함 (왼쪽 DEPT 가 다 나옴) -- RIGHT OUTER JOIN : 오른쪽 테이블(EMP)을 전부 보존 SELECT D.DEPTNO, D.DNAME, E.ENAME FROM DEPT D RIGHT OUTER JOIN EMP E ON D.DEPTNO = E.DEPTNO; -- → 14건 (EMP 는 전부 부서가 있으므로 INNER 와 결과 동일)
SQL
복사
종류
보존하는 쪽
의미
LEFT OUTER JOIN
왼쪽 테이블 전부
왼쪽 기준, 오른쪽 없으면 NULL
RIGHT OUTER JOIN
오른쪽 테이블 전부
오른쪽 기준, 왼쪽 없으면 NULL
FULL OUTER JOIN
양쪽 전부
어느 쪽이든 없으면 NULL
⭐ LEFT 와 RIGHT 는 테이블 순서만 바꾸면 서로 같습니다.A LEFT JOIN B = B RIGHT JOIN A

2) FULL OUTER JOIN — 양쪽 모두 보존

-- ============================================================ -- 【시험용 예제】 FULL OUTER JOIN — 짝 없는 양쪽을 모두 살림 ★ -- ============================================================ SELECT D.DEPTNO, D.DNAME, E.ENAME FROM DEPT D FULL OUTER JOIN EMP E ON D.DEPTNO = E.DEPTNO; -- → 15건 -- 40번 부서(사원 없음) + 모든 사원이 나온다 -- 만약 부서번호가 없는(50번 같은) 사원이 있었다면 그 사원도 나온다 -- -- ⭐ FULL OUTER JOIN = LEFT + RIGHT 를 합친 것 (중복 제거) -- ⚠️ Oracle (+) 문법으로는 FULL OUTER JOIN 을 만들 수 없다! (다음 절)
SQL
복사

4. (+) ↔ ANSI 대응 ⭐⭐

1) 양방향 변환표

Oracle (+) 문법
ANSI 표준 문법
WHERE D.DEPTNO = E.DEPTNO(+)
DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO
WHERE D.DEPTNO(+) = E.DEPTNO
DEPT D RIGHT JOIN EMP E ON D.DEPTNO = E.DEPTNO
불가능 ❌
DEPT D FULL JOIN EMP E ON D.DEPTNO = E.DEPTNO
⚠️ (+) 의 위치를 기억하는 법(+) 가 붙은 쪽이 "부족한 쪽" 입니다. E.DEPTNO(+) 면 EMP가 부족한 쪽 → DEPT가 보존됨 → LEFT (DEPT가 왼쪽이므로).

2) (+) 의 세 가지 한계 ⭐

한계
설명
FULL OUTER 불가
양쪽 동시 보존을 못 함 (ANSI만 가능) ⭐
양쪽에 (+) 불가
D.DEPTNO(+) = E.DEPTNO(+) → 오류
Oracle 전용
다른 DBMS에서 안 됨
-- ❌ 양쪽에 (+) 를 붙이면 오류 SELECT * FROM DEPT D, EMP E WHERE D.DEPTNO(+) = E.DEPTNO(+); -- ORA-01468: a predicate may reference only one outer-joined table -- → FULL OUTER 가 필요하면 반드시 ANSI FULL JOIN 을 써야 한다
SQL
복사

5. 표준 조인 문법 ⭐⭐⭐

1) 네 가지 표준 조인

문법
조인 조건
특징
INNER JOIN ~ ON
ON A.x = B.x
조건을 직접 명시 (가장 명확)
JOIN ~ USING(컬럼)
USING(DEPTNO)
컬럼명이 같을 때 간단히
NATURAL JOIN
(자동)
같은 이름 컬럼을 자동으로 조인
CROSS JOIN
없음
카티션 곱 (전체 조합)

2) INNER JOIN ~ ON — 표준 기본형

-- ============================================================ -- 【이해용 예제】 ON 으로 조인 조건을 명시 -- ============================================================ SELECT E.ENAME, D.DNAME FROM EMP E INNER JOIN DEPT D -- INNER 는 생략 가능 (그냥 JOIN) ON E.DEPTNO = D.DEPTNO; -- 조인 조건은 ON 절에 -- → 14건 (13강 EQUI JOIN 과 동일 결과)
SQL
복사

3) USING 과 NATURAL JOIN — 컬럼명 규칙 주의 ⭐⭐

-- ============================================================ -- 【시험용 예제】 USING / NATURAL JOIN 의 컬럼명 규칙 ★★ -- ============================================================ -- USING : 조인 기준 컬럼을 괄호로 지정 (양쪽 컬럼명이 같아야 함) SELECT ENAME, DNAME, DEPTNO -- ⚠️ DEPTNO 에 테이블명/별칭을 붙이면 안 된다! FROM EMP JOIN DEPT USING (DEPTNO); -- → 14건 -- ⚠️ SELECT E.DEPTNO ... USING(DEPTNO) → ORA-25154 오류 -- USING 에 쓴 컬럼은 '공통 컬럼' 이라 테이블 수식어를 붙일 수 없다 -- NATURAL JOIN : 같은 이름의 모든 컬럼을 '자동' 으로 조인 SELECT ENAME, DNAME, DEPTNO -- 여기도 DEPTNO 에 수식어 금지 FROM EMP NATURAL JOIN DEPT; -- → 14건 (EMP 와 DEPT 의 공통 컬럼인 DEPTNO 로 자동 조인) -- -- ⚠️ NATURAL JOIN 의 위험 -- 같은 이름의 컬럼이 '전부' 조인 조건이 된다. 우연히 같은 이름 컬럼이 하나 더 있으면 -- 의도치 않은 조인이 되어버린다. 그래서 실무에서는 잘 쓰지 않는다.
SQL
복사
세 문법의 컬럼 수식어 규칙 ⭐
문법
조인 컬럼에 테이블명/별칭
예
ON
붙여야 함
ON E.DEPTNO = D.DEPTNO
USING
붙이면 오류
USING (DEPTNO), SELECT도 그냥 DEPTNO
NATURAL JOIN
붙이면 오류
자동 조인, SELECT도 그냥 DEPTNO
⚠️ NATURAL JOIN 과 ON/USING 은 함께 쓸 수 없습니다. (택일)

4) CROSS JOIN — 의도적 카티션 곱

-- ============================================================ -- 【이해용 예제】 CROSS JOIN = 모든 조합 (카티션 곱) -- ============================================================ SELECT E.ENAME, D.DNAME FROM EMP E CROSS JOIN DEPT D; -- → 14 × 4 = 56건 (모든 사원 × 모든 부서) -- -- ⭐ 13강의 '실수로 발생한 카티션 곱' 을 '의도적으로' 만드는 문법이다. -- 조인 조건이 아예 없다.
SQL
복사

6. ON vs WHERE — OUTER JOIN의 결정적 함정 ⭐⭐⭐

🔥 같은 조건을 ON에 두느냐 WHERE에 두느냐로 OUTER가 INNER로 둔갑합니다.

1) 조건의 위치가 결과를 바꾼다

-- ============================================================ -- 【시험용 예제】 "부서별로 급여 2000 초과 사원" — 단 부서는 다 보이게 ★★★ -- ============================================================ -- ✅ 조건을 ON 에 두면 → OUTER 유지 (40번 부서 살아남음) SELECT D.DEPTNO, D.DNAME, E.ENAME, E.SAL FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO AND E.SAL > 2000; -- 조인 조건에 포함 → 조인 '시점' 에 필터 -- DEPTNO DNAME ENAME SAL -- ------ ---------- ------ ----- -- 10 ACCOUNTING KING 5000 -- 10 ACCOUNTING CLARK 2450 -- 20 RESEARCH JONES 2975 -- ... -- 40 OPERATIONS (NULL) (NULL) ← 40번 부서 살아남음 ✅ -- -- ❌ 조건을 WHERE 에 두면 → INNER 처럼 됨 (40번 부서 탈락!) SELECT D.DEPTNO, D.DNAME, E.ENAME, E.SAL FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO WHERE E.SAL > 2000; -- 조인 '후' 에 필터 -- DEPTNO DNAME ENAME SAL -- ------ ---------- ------ ----- -- 10 ACCOUNTING KING 5000 -- ... ← 40번 부서 사라짐! ⚠️
SQL
복사

2) 왜 그런가 — UNKNOWN이 터진다 ⭐

조건 위치
실행 시점
40번 부서(E.SAL=NULL)
결과
ON
조인 하면서 필터
조인은 되고 NULL로 채워짐
살아남음 ✅
WHERE
조인 후 필터
NULL > 2000 = UNKNOWN → 탈락
사라짐 ⚠️
⭐ 핵심 원칙
•
OUTER JOIN에서 보존하려는 쪽 조건은 반드시 ON 에 둔다.
•
WHERE 에 두면 NULL 행이 걸러져 사실상 INNER JOIN이 된다.
•
이것이 OUTER JOIN 문제의 최다 함정입니다.

7. SELF + OUTER JOIN — KING 살려내기 ⭐

13강에서 누락됐던 사장 KING을 드디어 살려냅니다.
-- ============================================================ -- 【시험용 예제】 모든 사원과 그 관리자 (관리자 없는 KING 포함) ★★ -- ============================================================ -- Oracle (+) 문법 SELECT E.ENAME AS 사원, M.ENAME AS 관리자 FROM EMP E, EMP M WHERE E.MGR = M.EMPNO(+); -- 관리자(M)가 부족한 쪽 → (+) -- 사원 관리자 -- ------ ------ -- SMITH FORD -- ... -- KING (NULL) ← 관리자가 없어도 KING 이 나온다! ✅ -- → 14건 (13강의 13건 + KING) -- ANSI 문법 (동일 결과) SELECT E.ENAME AS 사원, M.ENAME AS 관리자 FROM EMP E LEFT JOIN EMP M ON E.MGR = M.EMPNO; -- → 14건, KING 포함 -- -- ⭐ 05강 순환 관계 → 13강 SELF JOIN(KING 누락) → 14강 SELF OUTER JOIN(KING 복구) -- 세 강의에 걸친 이야기가 여기서 완결된다.
SQL
복사

8. 출제 포인트 한눈에 정리

#
꼭 외울 것
핵심
1
OUTER JOIN 목적
짝 없는 행도 NULL로 채워 보존
2
(+) 위치
데이터가 부족한 쪽에 붙임 ⭐
3
LEFT OUTER
왼쪽 테이블 전부 보존
4
RIGHT OUTER
오른쪽 테이블 전부 보존
5
LEFT ↔ RIGHT
테이블 순서만 바꾸면 동일
6
FULL OUTER
양쪽 전부 / (+)로 불가 ⭐
7
(+) 한계
FULL 불가, 양쪽 (+) 불가, Oracle 전용
8
INNER JOIN ~ ON
조인 조건을 ON 에
9
USING(컬럼)
공통 컬럼에 테이블명 못 붙임 ⭐
10
NATURAL JOIN
같은 이름 컬럼 자동 조인, 수식어 금지 ⭐
11
NATURAL JOIN + ON
함께 사용 불가
12
CROSS JOIN
카티션 곱 (전체 조합)
13
ON vs WHERE
OUTER에서 조건을 WHERE에 두면 INNER처럼 됨 ⭐⭐
14
보존할 쪽 조건
반드시 ON 에 둔다
15
SELF + OUTER
KING(MGR NULL)도 살림
16
표준 문법
ANSI는 조인/조회 조건이 분리됨

9. 확인 문제

Q1. DEPT 를 전부 보이게 하고 싶다. (+) 는 어느 쪽에 붙이는가?
SELECT * FROM DEPT D, EMP E WHERE D.DEPTNO ___ = ___ E.DEPTNO;
SQL
복사
정답 보기
Q2. A LEFT JOIN B 와 같은 결과를 내는 것은? ① A RIGHT JOIN B ② B RIGHT JOIN A ③ A INNER JOIN B ④ A CROSS JOIN B
정답 보기
Q3. Oracle (+) 문법으로 할 수 없는 조인은?
정답 보기
Q4. NATURAL JOIN 에 대한 설명으로 옳지 않은 것은? ① 같은 이름의 컬럼을 자동으로 조인한다 ② 조인 컬럼에 테이블명을 붙이면 오류가 난다 ③ ON 절과 함께 사용할 수 있다 ④ 같은 이름 컬럼이 여러 개면 모두 조인 조건이 된다
정답 보기
Q5. 다음 두 SQL의 결과 건수가 다른 이유는?
-- (A) FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO=E.DEPTNO AND E.SAL>2000 -- (B) FROM DEPT D LEFT JOIN EMP E ON D.DEPTNO=E.DEPTNO WHERE E.SAL>2000
SQL
복사
정답 보기
Q6. EMP CROSS JOIN DEPT 의 결과 건수는? (EMP 14행, DEPT 4행)
정답 보기