비등가 조인(Non EQUI JOIN)은 =가 아닌 조건으로 행을 잇습니다. 세 테이블 이상을 이을 때는 조인 조건이 적어도 '테이블 수 − 1'개 필요합니다.
사원마다 급여 등급을 보려면 EMP와 SALGRADE를 이어야 합니다. 그런데 SALGRADE에는 SAL과 같은 값이 아니라 급여 구간(LOSAL부터 HISAL까지)이 들어 있습니다. 같은 값끼리 잇는 등가 조인(EQUI JOIN)으로는 경곗값(구간 양 끝의 값)이 우연히 같은 사원만 이어집니다. 그래서 SAL이 구간 안에 드는지를 조인 조건으로 씁니다. 부서 이름과 급여 등급을 한 줄에 보려면 EMP·DEPT·SALGRADE 세 테이블을 이어야 합니다.
1비등가 조인
E.SAL = S.LOSAL로 이으면 SAL이 어느 등급의 LOSAL과 똑같은 최유나(450)만 등급을 얻습니다.
E.SAL = S.HISAL로 이으면 한 사원도 등급을 얻지 못합니다.
SAL은 한 값이고 등급은 구간이라, 같은 값을 찾는 =로는 맞지 않습니다.
BETWEEN으로 이으면 SAL이 LOSAL과 HISAL 사이에 드는 등급과 이어집니다.
BETWEEN은 양 끝을 포함하므로, 450은 HISAL이 449인 3등급이 아니라 LOSAL이 450인 4등급에 듭니다.
등급 구간이 0부터 9999까지 겹치지도 비지도 않아서 사원마다 등급이 하나씩 이어지고, 결과는 6행입니다.
이처럼 =가 아닌 조건으로 잇는 조인이 비등가 조인입니다.
구간의 모양이 달라지면 결과도 달라집니다.
| 구간이 | 한 SAL 값은 | 결과 |
|---|---|---|
| 이어짐(지금) | 등급 하나와 이어짐 | 사원마다 한 줄 |
| 겹침 | 두 등급과 이어짐 | 행이 늘어남 |
| 빔 | 어느 등급과도 안 이어짐 | 내부 조인에서 빠짐 |
2세 테이블 이상 조인
테이블이 N개면 둘씩 잇는 조건이 적어도 N − 1개 필요하므로, 여기서는 둘을 씁니다.
EMP와 DEPT는 E.DEPTNO = D.DEPTNO로, EMP와 SALGRADE는 BETWEEN 조건으로 잇습니다.
내부 조인은 어느 한 조건에서라도 짝이 없는 행을 버립니다. DEPTNO가 NULL인 정하늘은 등급은 있지만 부서와 짝이 없어 빠지고, 결과는 5행입니다. 정하늘도 남기려면 EMP와 DEPT 사이만 외부 조인으로 바꿉니다.
3조건이 빠지면 — 카티션 곱
SALGRADE 쪽 조건을 빼면 남은 5행 하나하나가 등급 다섯과 모두 짝지어져 25행이 됩니다. 조건이 하나도 없으면 6 × 4 × 5 = 120행입니다. 이렇게 조건 없이 모든 행끼리 짝지어진 결과를 카티션 곱(Cartesian product)이라 합니다. 카티션 곱을 일부러 만드는 문법은 CROSS JOIN(조건 없이 모든 행끼리 짝짓는 조인 — 표준 조인 레슨에서 자세히)입니다.
예제
행 순서를 정하려고 ORDER BY E.EMPNO를 붙였습니다.
=로 이으면 1행만 나옵니다.
SELECT E.EMPNO,
E.ENAME,
E.SAL,
S.GRADE
FROM EMP E, SALGRADE S
WHERE E.SAL = S.LOSAL
ORDER BY E.EMPNO;
| EMPNO | ENAME | SAL | GRADE |
|---|---|---|---|
| 1004 | 최유나 | 450 | 4 |
비등가 조인입니다.
SELECT E.EMPNO,
E.ENAME,
E.SAL,
S.GRADE
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN
S.LOSAL AND S.HISAL
ORDER BY E.EMPNO;
| EMPNO | ENAME | SAL | GRADE |
|---|---|---|---|
| 1001 | 김민준 | 520 | 5 |
| 1002 | 이서연 | 380 | 2 |
| 1003 | 박지호 | 410 | 3 |
| 1004 | 최유나 | 450 | 4 |
| 1005 | 정하늘 | 300 | 1 |
| 1006 | 강도윤 | 470 | 4 |
BETWEEN 대신 >=와 <=로 써도 같습니다.
표준 조인 문법으로 쓰면 조건이 ON에 들어가고, 결과는 위와 같은 6행입니다.
SELECT E.EMPNO,
E.ENAME,
E.SAL,
S.GRADE
FROM EMP E
JOIN SALGRADE S
ON E.SAL >= S.LOSAL
AND E.SAL <= S.HISAL
ORDER BY E.EMPNO;
세 테이블 조인입니다. 조인 조건을 둘 씁니다.
SELECT E.EMPNO,
E.ENAME,
D.DNAME,
E.SAL,
S.GRADE
FROM EMP E, DEPT D, SALGRADE S
WHERE E.DEPTNO = D.DEPTNO
AND E.SAL BETWEEN
S.LOSAL AND S.HISAL
ORDER BY E.EMPNO;
| EMPNO | ENAME | DNAME | SAL | GRADE |
|---|---|---|---|---|
| 1001 | 김민준 | 기획 | 520 | 5 |
| 1002 | 이서연 | 개발 | 380 | 2 |
| 1003 | 박지호 | 개발 | 410 | 3 |
| 1004 | 최유나 | 영업 | 450 | 4 |
| 1006 | 강도윤 | 개발 | 470 | 4 |
표준 조인 문법으로는 JOIN마다 ON을 씁니다. EMP와 DEPT 사이를 외부 조인으로 바꾸면, 정하늘(DNAME NULL, 1등급)이 더해져 6행이 됩니다.
SELECT E.EMPNO,
E.ENAME,
D.DNAME,
E.SAL,
S.GRADE
FROM EMP E
LEFT OUTER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO
JOIN SALGRADE S
ON E.SAL BETWEEN
S.LOSAL AND S.HISAL
ORDER BY E.EMPNO;
SALGRADE 쪽 조건을 빼고 행 수를 셉니다.
SELECT COUNT(*) AS CNT
FROM EMP E, DEPT D, SALGRADE S
WHERE E.DEPTNO = D.DEPTNO;
| CNT |
|---|
| 25 |
조인 조건을 하나도 쓰지 않으면 120행입니다.
SELECT COUNT(*) AS CNT
FROM EMP E, DEPT D,
SALGRADE S;
| CNT |
|---|
| 120 |
시험 포인트
=로 잇는 조인이 등가 조인(EQUI JOIN),BETWEEN·>·>=·<·<=처럼=가 아닌 조건으로 잇는 조인이 비등가 조인(Non EQUI JOIN)입니다.- BETWEEN은 양 끝을 포함합니다. 경곗값이 어느 구간에 드는지 LOSAL·HISAL로 따져 봅니다.
- 구간이 겹치면 한 값이 두 등급과 이어져 행이 늘고, 빈 곳의 값은 내부 조인에서 빠집니다.
- 테이블이 N개면 조인 조건은 적어도 N − 1개입니다. 조건이 빠지면 그 테이블과는 카티션 곱이 되어 행 수가 곱으로 늡니다.
- 세 테이블 내부 조인에서는 어느 한 조건에서라도 짝이 없는 행이 빠집니다. 남기려면 그 사이를 외부 조인으로 씁니다.
확인 문제
1. 월급 10000인 사원 1007을 EMP에 넣고 비등가 조인을 돌리면 결과는 몇 행일까요?
INSERT INTO EMP
VALUES (1007, '한지우',
10000, 10, 1001);
SELECT COUNT(*) AS CNT
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN
S.LOSAL AND S.HISAL;
정답
6행입니다.
| CNT |
|---|
| 6 |
5등급의 HISAL이 9999라서 10000은 어느 구간에도 들지 않습니다. 짝이 없는 1007은 내부 조인에서 빠지고, 원래 6명만 남습니다.
2. 세 테이블을 FROM에 쓰고, WHERE에는 SALGRADE 쪽 조건 하나만 썼습니다. 결과는 몇 행일까요?
SELECT COUNT(*) AS CNT
FROM EMP E, DEPT D, SALGRADE S
WHERE E.SAL BETWEEN
S.LOSAL AND S.HISAL;
정답
24행입니다.
| CNT |
|---|
| 24 |
EMP와 SALGRADE는 BETWEEN 조건으로 이어져 6행이 됩니다. DEPT와 잇는 조건이 없어서 이 6행이 DEPT 4행과 모두 짝지어지고, 6 × 4 = 24행이 됩니다.
3. SALGRADE의 3등급 HISAL을 459로 고쳐 4등급(450~499)과 겹치게 했습니다. 비등가 조인의 결과는 몇 행이고, 누가 두 번 나올까요?
UPDATE SALGRADE
SET HISAL = 459
WHERE GRADE = 3;
SELECT E.EMPNO,
E.ENAME,
E.SAL,
S.GRADE
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN
S.LOSAL AND S.HISAL
ORDER BY E.EMPNO, S.GRADE;
정답
7행이고, 최유나가 두 번 나옵니다.
| EMPNO | ENAME | SAL | GRADE |
|---|---|---|---|
| 1001 | 김민준 | 520 | 5 |
| 1002 | 이서연 | 380 | 2 |
| 1003 | 박지호 | 410 | 3 |
| 1004 | 최유나 | 450 | 3 |
| 1004 | 최유나 | 450 | 4 |
| 1005 | 정하늘 | 300 | 1 |
| 1006 | 강도윤 | 470 | 4 |
450은 3등급(400~459)에도, 4등급(450~499)에도 듭니다. 강도윤(470)은 459보다 커서 4등급 하나와만 이어집니다.