[Oracle 기초] OUTER JOIN

Posted by 열정보이
2018. 12. 31. 14:51 Oracle

오늘은 OUTER JOIN에 대해 알아볼까 합니다.


우리가 흔히 알고있는 JOIN은 INNER 조인이라고 하죠.


보통 아래와 같은 모습으로 사용되곤 합니다.


1
2
3
4
5
SELECT * FROM BUY_HIS B JOIN PRODUCT_TABLE P
ON B.PRODUCT_CODE = P.PRODUCT_CODE;
 
SELECT * FROM BUY_HIS B, PRODUCT_TABLE P
WHERE B.PRODUCT_CODE = P.PRODUCT_CODE;
cs


INNER JOIN을 사용하게 되면 ON을 통해 JOIN 조건을 주는 것과, WHERE를 통해 JOIN 조건을 주는 것 모두 결과 값이 동일합니다.

다만 위에 표기법이 공인..? 표기법이기 때문에 DB를 교체하더라도 SQL를 변경할 필요가 없겠죠.


하지만 ON 과 WHERE에 조인조건을 주는 것은 OUTER JOIN에서는 다르다는 점!! 기억하셔야 합니다.

이 내용은 다음 컨텐츠에서 정리해보도록 할게요!!


본격적으로 OUTER JOIN에 대해 알아보도록 하겠습니다.

위와 같은 2개의 테이블이 있다고 가정하겠습니다.


PRODUCT_TABLE은 상품 정보를 담고있는 테이블입니다.

그리고 BUY_HIS 테이블은 구매 내역을 담고있는 테이블이라고 생각하시면 됩니다.


JOIN을 하기 위해서는 두 테이블간 연관되는 COLUMN이 존재해야 합니다. 여기서는 PRODUCT_CODE가 되겠네요.


저는 사전에 테이블을 만들 때, PRODUCT_TABLE의 PK를 PRODUCT_CODE로 잡아주고, BUY_HIS 테이블의 PRODUCT_CODE를 FK로 잡아주었습니다.




여기서 PK와 FK가 왜 필요할까요?


PK를 설정하게 되면 해당 컬럼은 NOT NULL 즉, NULL 값을 허용하지 않습니다. 

또한 UNIQUE와 동일하게 중복되는 값도 허용하지 않습니다. 

심지어 해당 컬럼은 자동으로 인덱스까지 설정해주니 PK 준 컬럼을 WHERE 조건을 통해 이용하면 검색 속도를 증가시킬 수 있겠죠?


그럼 FK는 왜 설정할까요?

저 같은 경우는 무결성 문제라고 생각합니다.

만약 BUY_HIS 테이블이 PRODUCT_TABLE과 JOIN을 시도하려고 합니다. 그런데 PRODUCT_CODE가 중복되는 값이 존재한다면?

JOIN이 이뤄지지 않겠죠?

왜냐하면 INNER JOIN의 경우 '두 테이블간의 연관된 KEY의 짝을 맞춰주는 것'이기 때문입니다. 아래 사진과 같이 말이죠.

위 사진 처럼 되면 P001을 통해 중복되는 ROW가 발생하게 됩니다.


FK를 설정하게 되면 이러한 문제를 사전에 막아줄 수 있습니다.

즉 FK로 설정되는 부모 테이블의 KEY 값은 중복되지 않는 값만 존재하게 하기 때문이죠.


또한, 부모 테이블의 값이 제거되었을 경우, CASECADE 옵션을 주어 자식 테이블의 해당 값을 가진 ROW를 제거하여 무결성을 유지해 줄 수 있습니다. 

FK를 설정하지 않는다면 우리는 이러한 작업을 다 수동으로 해야 하고, 중복이나 제거에 대한 작업을 고려해야 되겠죠?




다시 본론으로 돌아오겠습니다.


위의 두 테이블을 JOIN한 값은 어떤 결과를 나타낼까요?



바로 위와 같습니다.

INNER JOIN은 '짝 맞추기' 이기 때문에 값이 존재하지 않으면 JOIN 자체를 실행하지 않죠.


하지만 우리는 값이 없더라도 JOIN을 해야 하는 상황이 존재합니다.

그럴 경우 OUTER JOIN을 사용하게 되는거죠.


OUTER JOIN은 DRIVING TABLE(JOIN을 주도하는 테이블) 의 값이 JOIN이 되는 TABLE에 존재하지 않을 경우 NULL 값을 출력하여 가져옵니다. 직접 보도록 하겠습니다.


1
2
3
SELECT * FROM BUY_HIS B RIGHT OUTER JOIN PRODUCT_TABLE P
ON B.PRODUCT_CODE = P.PRODUCT_CODE
ORDER BY B.HIS_NUMBER;
cs


다음과 같은 쿼리의 결과는 아래와 같습니다.



쿼리를 보게 되면 JOIN 대신 RIGHT(LEFT) OUTER JOIN을 명시해 주었습니다.

RIGHT OUTER JOIN 이라고 명시하게 되면 DRIVING TABLE이 오른쪽에 있는 PRODUCT_TABLE이 되는거죠.


즉, JOIN 시 JOIN 조건에 해당하는 PRODUCT_CODE 값이 BUY_HIS 테이블에 존재하지 않더라도, PRODUCT_TABLE에 존재하는 PRODUCT_CODE 값은 모두 값을 반환하고, BUY_HIS 테이블에 존재하는 컬럼은 NULL로 값을 반환한다는 의미가 되겠습니다.


Oracle에서는 OUTER JOIN을 좀 더 간편하게 사용할 수 있습니다.


1
2
3
SELECT * FROM BUY_HIS B, PRODUCT_TABLE P
WHERE B.PRODUCT_CODE(+= P.PRODUCT_CODE
ORDER BY B.HIS_NUMBER;
cs


두 쿼리에 대한 결과 값은 동일합니다.

즉, (+)가 붙은 테이블이 NULL 값을 표현한다는거죠.

저 쿼리는 RIGHT OUTER JOIN 입니다.

(+) 가 반대편에 붙어있어서 헷갈리긴 하지만 RIGHT OUTER JOIN 인거죠..


뭐 언젠가는 익숙해 지겠죠?


그럼 다음에는 OUTER JOIN에서의 ON과 WHERE의 차이에 대해 알아보도록 하겠습니다.