본문으로 건너뛰기

조인

SQLD 목차SQL 기본레슨 21 / 35

목차

조인(JOIN)은 두 테이블에서 조인 조건이 맞는 행끼리 이어 한 줄로 만듭니다. 외부 조인(OUTER JOIN)은 짝이 없는 행도 남기고 빈칸을 NULL로 채웁니다.

EMP 테이블에는 사원의 부서 번호(DEPTNO)만 있고, 부서 이름(DNAME)은 DEPT 테이블에 있습니다. 사원 이름과 부서 이름을 한 줄에 보려면 두 테이블을 이어야 합니다. 이때 짝이 없는 행을 버리느냐 남기느냐에 따라 내부 조인(INNER JOIN)과 외부 조인으로 나뉩니다.

8단계 중 1단계. 같은 열. 사원 줄 옆에 부서 이름(DNAME)을 붙이려 합니다. 두 테이블에 다 있는 DEPTNO 열로 잇습니다.

1조인 조건과 등가 조인

E·D는 FROM 절에서 EMP·DEPT에 붙인 테이블 별칭입니다. E.DEPTNO = D.DEPTNO처럼 행을 잇는 조건이 조인 조건이고, 짝은 여럿일 수 있습니다. DEPT의 20번 개발 행은 사원 셋과 짝지어져 결과에 세 번 나옵니다. 이처럼 =로 같은 값끼리 잇는 조인을 등가 조인(EQUI JOIN)이라 합니다.

별칭을 붙인 쿼리 안에서는 EMP.ENAME이 아니라 E.ENAME으로 씁니다(어기면 ORA-00904). 두 테이블에 다 있는 DEPTNO는 E.DEPTNO처럼 어느 쪽 열인지 밝힙니다(빠뜨리면 ORA-00918). Oracle은 테이블 별칭 앞에 AS를 받지 않아 FROM EMP AS E는 오류입니다.

2내부 조인과 짝 없는 행

정하늘(1005)은 DEPTNO가 NULL이라 어떤 값과 견줘도 알 수 없음이 되어 짝이 없습니다. 40번 인사 부서는 사원이 없습니다. 둘은 잘못된 데이터가 아니라 짝이 없을 뿐이지만, 짝이 있는 행만 남기는 내부 조인(INNER JOIN)에서는 빠집니다.

INNER JOIN … ON처럼 FROM 절에 조인 키워드를 쓰는 꼴이 표준 조인(STANDARD JOIN)입니다. 테이블을 쉼표로 늘어놓고 조인 조건을 WHERE에 써도 내부 조인이 됩니다. INNER는 생략할 수 있어, JOIN만 쓰면 내부 조인입니다.

3외부 조인

외부 조인이 짝 없는 행을 남기는 쪽은 테이블을 JOIN의 어느 쪽에 썼느냐로 정합니다. LEFT는 왼쪽, RIGHT는 오른쪽, FULL은 양쪽 테이블의 행을 모두 남깁니다. 그래서 DEPT D RIGHT OUTER JOIN EMP E⁠는 EMP E LEFT OUTER JOIN DEPT D⁠와 같은 6행입니다. 그림 결과 표 끝 칸의 ✓·✕가 짝 없던 두 줄이 남는지 보입니다.

조인정하늘 줄40번 부서 줄행 수
INNER JOIN✕✕5
LEFT OUTER JOIN✓✕6
RIGHT OUTER JOIN✕✓6
FULL OUTER JOIN✓✓7

행 수는 짝이 있는 5행에 남긴 짝 없는 행을 더합니다. OUTER도 생략할 수 있어 LEFT JOIN은 LEFT OUTER JOIN과 같습니다.

4Oracle의 (+) 표기

Oracle은 쉼표 조인의 WHERE 조건에 (+)를 붙여 외부 조인을 씁니다. (+)는 NULL로 채워지는 쪽 테이블의 열에 붙이고, (+)가 없는 쪽 테이블의 행이 모두 남습니다. 완전 외부 조인은 (+)로 쓸 수 없습니다. 조건 양쪽에 붙이면 ORA-01468 오류가 나므로 FULL OUTER JOIN으로 씁니다.

예제

네 조인은 INNER JOIN 자리의 키워드만 다르고, 결과는 그림의 표와 같습니다.

SELECT E.EMPNO,
  E.ENAME,
  D.DEPTNO,
  D.DNAME
FROM EMP E
  INNER JOIN DEPT D
  ON E.DEPTNO = D.DEPTNO
ORDER BY E.EMPNO;
EMPNOENAMEDEPTNODNAME
1001김민준10기획
1002이서연20개발
1003박지호20개발
1004최유나30영업
1006강도윤20개발

쉼표와 WHERE로 쓴 내부 조인입니다. 결과는 위와 같은 5행입니다.

SELECT E.EMPNO,
  E.ENAME,
  D.DEPTNO,
  D.DNAME
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
ORDER BY E.EMPNO;

(+)로 쓴 외부 조인입니다. EMP의 행이 모두 남아 LEFT OUTER JOIN과 같은 6행입니다.

SELECT E.EMPNO,
  E.ENAME,
  D.DEPTNO,
  D.DNAME
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO(+)
ORDER BY E.EMPNO;
EMPNOENAMEDEPTNODNAME
1001김민준10기획
1002이서연20개발
1003박지호20개발
1004최유나30영업
1005정하늘NULLNULL
1006강도윤20개발

시험 포인트

  • 조인 열이 NULL인 행은 어떤 값과도 짝이 되지 않아 내부 조인에서 늘 빠집니다.
  • LEFT는 JOIN 왼쪽, RIGHT는 오른쪽 테이블의 행을 모두 남깁니다. 테이블 자리를 바꾸면 LEFT와 RIGHT도 바뀝니다.
  • 행 수는 내부 조인 행에 남긴 짝 없는 행을 더한 수입니다.
  • 두 테이블에 다 있는 열은 E.DEPTNO처럼 밝히고, 별칭을 붙였으면 EMP.ENAME이 아니라 E.ENAME으로 씁니다. Oracle은 테이블 별칭 앞에 AS를 쓸 수 없습니다.
  • Oracle (+)는 NULL로 채워지는 쪽 열에 붙이고, 반대쪽 테이블의 행이 모두 남습니다. 완전 외부 조인은 (+)로 쓸 수 없습니다.

확인 문제

1. 다음 쿼리는 무엇을 찾는 쿼리이고, 결과는 무엇일까요?

SELECT E.EMPNO,
  E.ENAME
FROM EMP E
  LEFT OUTER JOIN DEPT D
  ON E.DEPTNO = D.DEPTNO
WHERE D.DEPTNO IS NULL;
정답

부서와 짝이 없는 사원을 찾는 쿼리입니다.

EMPNOENAME
1005정하늘

LEFT OUTER JOIN 결과에서 DEPT 쪽 칸이 NULL인 줄은 짝이 없던 정하늘 줄뿐입니다.

2. DEPT에 소속 사원이 없는 50번 총무 부서를 하나 더 넣으면, 네 조인의 결과는 각각 몇 행일까요?

정답

50번 부서는 40번처럼 짝이 없는 DEPT 행이 됩니다. 그래서 DEPT의 행을 모두 남기는 RIGHT와 FULL만 한 행씩 늘어납니다.

INNER 5행 · LEFT 6행 · RIGHT 7행 · FULL 8행입니다. 넣는 문장은 아래와 같습니다.

INSERT INTO DEPT
VALUES (50, '총무',
    '대전');

3. 다음 Oracle 쿼리를 표준 조인으로 바꾸려고 합니다.

SELECT E.EMPNO,
  E.ENAME,
  D.DEPTNO,
  D.DNAME
FROM EMP E, DEPT D
WHERE E.DEPTNO(+) = D.DEPTNO
ORDER BY E.EMPNO;

바꾼 쿼리의 FROM 절은 아래 꼴입니다. 빈칸에 들어갈 조인은 무엇이고, 결과는 몇 행일까요?

FROM EMP E
  ______ DEPT D
  ON E.DEPTNO = D.DEPTNO
정답

RIGHT OUTER JOIN이고, 결과는 6행입니다. (+)가 EMP 쪽에 붙었으니 EMP 쪽이 NULL로 채워지고, (+)가 없는 DEPT의 행이 모두 남습니다. 빈칸 왼쪽이 EMP이므로, 오른쪽 DEPT를 모두 남기는 RIGHT OUTER JOIN이 됩니다.

EMPNOENAMEDEPTNODNAME
1001김민준10기획
1002이서연20개발
1003박지호20개발
1004최유나30영업
1006강도윤20개발
NULLNULL40인사

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

SQLD 목차로