예를 들어, 사원이 없는 부서를 찾고자 한다.
결과셋은 다음과 같아야 한다.
DEPTNO DNAME LOC
------ ---------- -------
40 OPERATIONS BOSTON
'EMP'와 'DEPT'를 동등조건으로 JOIN한다면 사원이 없는 부서를 반환하지 않을 것이다.
JOIN 조건을 충족하지 않는 'DEPT'의 행만을 원한다.
앞선 레시피에서는 'EMP' 테이블에 존재하지 않는 부서번호만 가지고 왔다.
이번 레시피를 사용하면 'DEPT' 테이블에서 다른 열을 쉽게 반환할 수 있으며, 심지어 원하는 열만을 반환할 수도 있게 된다.
NULL
에 대한 외부조인(OUNTER JOIN
) 및 필터를 사용한다. OUTER
라는 키워드는 선택사항이다. (?)select d.*
from dept d left outer join emp e
on (d.deptno = e.deptno)
where e.deptno is null
>>
+--------+------------+--------+
| deptno | dname | loc |
+--------+------------+--------+
| 40 | OPERATIONS | BOSTON |
+--------+------------+--------+
OUTER JOIN
후 일치하지 않는 행만 유지하는 방식으로 작동한다.where e.deptno is null
이 처리 되지 않은 상태의 결과셋부터 봐야겠다.
select d.*
from dept d left outer join emp e
on (d.deptno = e.deptno)
+--------+------------+----------+
| deptno | dname | loc |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 10 | ACCOUNTING | NEW YORK |
| 10 | ACCOUNTING | NEW YORK |
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 20 | RESEARCH | DALLAS |
| 20 | RESEARCH | DALLAS |
| 20 | RESEARCH | DALLAS |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 30 | SALES | CHICAGO |
| 30 | SALES | CHICAGO |
| 30 | SALES | CHICAGO |
| 30 | SALES | CHICAGO |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
JOIN
을 실행했을 때 DEPTNO
의 값이 40인 'DEPT' 테이블에 JOIN
이 되는 'EMP' 테이블의 칼럼 값들은 NULL
로 처리 된다아래와 같이 나온단 뜻이다
# SELECT절만 바뀌었다(d.*에서 *으로)
select *
from dept d left outer join emp e
on (d.deptno = e.deptno)
>>
+--------+------------+----------+-------+--------+-----------+------+------------+------+------+--------+
| deptno | dname | loc | empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+------------+----------+-------+--------+-----------+------+------------+------+------+--------+
| 10 | ACCOUNTING | NEW YORK | 7777 | IREN | TESTER | 0 | 2022-07-03 | 9000 | 9000 | 10 |
| 10 | ACCOUNTING | NEW YORK | 7782 | CLARK | MANAGER | 7698 | 2006-06-09 | 2450 | NULL | 10 |
| 10 | ACCOUNTING | NEW YORK | 7839 | KING | PRESIDENT | NULL | 2006-11-17 | 5000 | NULL | 10 |
| 10 | ACCOUNTING | NEW YORK | 7934 | MILLER | CLERK | 7782 | 2007-01-23 | 1300 | NULL | 10 |
| 20 | RESEARCH | DALLAS | 7369 | SMITH | CLERK | 7902 | 2005-12-17 | 800 | NULL | 20 |
| 20 | RESEARCH | DALLAS | 7566 | JONES | MANAGER | 7839 | 2006-04-02 | 2975 | NULL | 20 |
| 20 | RESEARCH | DALLAS | 7788 | SCOTT | ANALYST | 7566 | 2007-12-09 | 3000 | NULL | 20 |
| 20 | RESEARCH | DALLAS | 7876 | ADAMS | CLERK | 7788 | 2008-01-12 | 1100 | NULL | 20 |
| 20 | RESEARCH | DALLAS | 7902 | FORD | ANALYST | 7566 | 2006-12-03 | 3000 | NULL | 20 |
| 30 | SALES | CHICAGO | 7499 | ALLEN | SALESMAN | 7698 | 2006-02-20 | 1600 | 300 | 30 |
| 30 | SALES | CHICAGO | 7521 | WARD | SALESMAN | 7698 | 2006-02-22 | 1250 | 500 | 30 |
| 30 | SALES | CHICAGO | 7654 | MARTIN | SALESMAN | 7698 | 2006-09-28 | 1250 | 1400 | 30 |
| 30 | SALES | CHICAGO | 7698 | BLAKE | MANAGER | 7839 | 2006-05-01 | 2850 | NULL | 30 |
| 30 | SALES | CHICAGO | 7844 | TURNER | SALESMAN | 7698 | 2006-09-08 | 1500 | 0 | 30 |
| 30 | SALES | CHICAGO | 7900 | JAMES | CLERK | 7698 | 2006-12-03 | 950 | 0 | 30 |
| 40 | OPERATIONS | BOSTON | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+--------+------------+----------+-------+--------+-----------+------+------------+------+------+--------+
맨 아랫줄
NULL
처리 되었다따라서 이 상태에서 NULL
처리된 자료만 남기면, 'DEPT' 테이블에는 존재하지만 'EMP' 테이블에는 존재하지 않는 행이 반환되게 된다.
ON
구문에서 KEY를 설정하고 이에 대한 JOIN
을 실행했을 때 NULL
값이 나오도록 유도한다WHERE
절에서 NULL
값만 남기면 두 테이블 사이에 다른 행을 찾을 수 있게 된다매우 획기적이다...
JOIN
을 이렇게도 쓸 수 있구나 싶다
이 다음 부분을 진행하기 전에, JOIN
의 종류와 개념을 먼저 정리한 후 진행해야겠다.