SQL Cook: 3. 11장 여러 테이블에서 누락된 데이터 반환하기

0

SQL_COOK

목록 보기
24/35
post-thumbnail

Q. 여러 테이블에서 누락된 데이터를 동시에 반환하려고 한다

사원이 없는 부서를 찾고자한다. 'DEPT' 테이블에서, 'EMP' 테이블에 없는 행을 반환하려 한다면 OUTER JOIN이 필요하다.

사원이 있는 경우에만 'DEPT' 테이블의 모든 'DEPTNO' 및 'DNAME'을 각 부서의 모든 사원명과 함께 반환하려면?

일단 'DEPT' 테이블에 'DEPTNO'가 동일한 'EMP' 테이블을 끼얹어보겠다.

select d.deptno, d.dname, e.ename
		from dept d left outer join emp e
        on d.deptno = e.deptno
>>
DEPTNO	DNAME	ENAME
10	ACCOUNTING	KING
30	SALES		BLAKE
10	ACCOUNTING	CLARK
20	RESEARCH	JONES
20	RESEARCH	SCOTT
20	RESEARCH	FORD
20	RESEARCH	SMITH
30	SALES		ALLEN
30	SALES		WARD
30	SALES		MARTIN
30	SALES		TURNER
20	RESEARCH	ADAMS
30	SALES		JAMES
10	ACCOUNTING	MILLER
40	OPERATIONS	  - 

15 rows selected.

마지막행의 'OPERATIONS'에 사원이 없는데도 행이 반환되고 있다.

  • 'EMP' 테이블에는 부서값이 40인 행이 없는데, 이를 'DEPT' 테이블에 OUTER JOIN 했기 때문이다
  • 'DEPT' 테이블은 LEFT JOIN의 왼쪽이므로, 모든 행이 반환된다

이 상태에서 부서값이 없는 사원 한 명을 추가해보겠다.
부서값이 없는 사원에 대한 행이 있을 떄, 위의 결과셋은 어떻게 반환될까?

insert into emp values(
1111, 'yoda', 'jedi', NULL
, to_date('19-11-3022','dd-mm-yyyy')
, 15000, 20000, null
);

select d.deptno, d.dname, e.ename
		from dept d right outer join emp e
        on d.deptno = e.deptno
>>
DEPTNO	DNAME	ENAME
10	ACCOUNTING	KING
10	ACCOUNTING	CLARK
10	ACCOUNTING	MILLER
20	RESEARCH	JONES
20	RESEARCH	SCOTT
20	RESEARCH	FORD
20	RESEARCH	SMITH
20	RESEARCH	ADAMS
30	SALES		BLAKE
30	SALES		ALLEN
30	SALES		WARD
30	SALES		MARTIN
30	SALES		TURNER
30	SALES		JAMES
 - 	  - 		yoda
15 rows selected.

RIGHT JOIN을 해보았지만 이번엔 OPERATION 부서가 누락되었다.

원하는 결과셋의 마지막은 아래와 같아야한다.

...
30	SALES		TURNER
30	SALES		JAMES
40  OPERTAION	  -
 - 	  - 		YODA

그렇다면 그냥 RIGHT JOINLEFT JOIN을 동시에 쓰면 되지 않을까?

A. FULL OUTER JOIN을 명시적으로 사용하여 일치 하는 행과 함께 두 테이블에서 누락된 모든 행을 반환한다

select d.deptno, d.dname, e.ename
	from dept d full outer join emp e
    on d.deptno = e.deptno
>>
DEPTNO	DNAME	ENAME
 - 	 - 			yoda
10	ACCOUNTING	KING
30	SALES		BLAKE
10	ACCOUNTING	CLARK
20	RESEARCH	JONES
20	RESEARCH	SCOTT
20	RESEARCH	FORD
20	RESEARCH	SMITH
30	SALES		ALLEN
30	SALES		WARD
30	SALES		MARTIN
30	SALES		TURNER
20	RESEARCH	ADAMS
30	SALES		JAMES
10	ACCOUNTING	MILLER
40	OPERATIONS	 - 
16 rows selected.

된다 😮
좀 아쉬운 점이 있다면 FULL OUTER JOIN은 MARIA에서 지원하지 않는다는 것이다.
사실 좀 아쉬운 게 아니라 심각하게 아쉽긴하다.

하지만 사실 엄청 간단한 방법이 있다.

  • RIGHT JOINLEFT JOIN의 결과를 합쳤다고 했다
  • 그렇다면 UNION을 사용하여 해결할 수 있다
  • 두 결과셋을 포개버리는 것이다
select d.deptno, d.dname, e.ename
	from dept d left join emp e
    on d.deptno = e.deptno
UNION
select d.deptno, d.dname, e.ename
	from dept d right join emp e
    on d.deptno = e.deptno
>>
DEPTNO	DNAME	ENAME
 - 	 	- 		yoda
10	ACCOUNTING	KING
30	SALES		BLAKE
10	ACCOUNTING	CLARK
20	RESEARCH	JONES
20	RESEARCH	SCOTT
20	RESEARCH	FORD
20	RESEARCH	SMITH
30	SALES		ALLEN
30	SALES		WARD
30	SALES		MARTIN
30	SALES		TURNER
20	RESEARCH	ADAMS
30	SALES		JAMES
10	ACCOUNTING	MILLER
40	OPERATIONS	 - 

MARIA에 'YODA'자료 넣기가 귀찮아서 Oracle로 출력한 결과셋.


정리

  • NULL값에 관련 없이, 모든 테이블의 모든 행을 반환하고 싶다면 FULL OUTER JOIN을 사용한다
  • 여의치 않을 경우, LEFT JOINRIGHT JOIN의 결과셋을 UNION으로 포개준다

OUTER JOIN의 쓰임새가 다양하게 나오고 있다.
NULL값을 찾는다거나, 가능한 한 모든 행을 반환하는 데엔 이만 한 게 없는 것 같다.

0개의 댓글