아우터 조인(OUTER JOIN)은 이너 조인(INNER JOIN)과 마찬가지로 데이터와 데이터를 결합하는 조인의 한 종류다. 이너 조인은 조인 조건을 만족하는 데이터만 결합해 조인 결과로 내보내는 반면에 아우터 조인은 조인 조건에 만족하지 않는 데이터도 결과에 포함하는 특징이 있다.
아우터 조인의 특징을 정리해보면 다음과 같다.
다음 데이터를 조인하지 말고 각각 조회해보자.
-- [SQL-7-9-1] S070, S071 Shop 정보
SELECT T1.ShopId ,T1.ShopNm, T1.ShopSt
FROM startdb.Shop T1
WHERE T1.ShopId IN ('S070','S071');
ShopId ShopNm ShopSt
------ ------------ ------
S070 San Jose-4th OPEN
S071 Austin-4th OPEN
-- [SQL-7-9-2] S070, S071 Ord 정보(S070 없음)
SELECT T2.ShopId ,T2.OrdNo ,T2.OrdDtm
FROM startdb.Ord T2
WHERE T2.ShopId IN ('S070','S071')
AND T2.OrdDtm >= STR_TO_DATE('20221121','%Y%m%d')
AND T2.OrdDtm <= STR_TO_DATE('20221122','%Y%m%d')
ORDER BY T2.ShopId ,T2.OrdNo;
ShopId OrdNo OrdDtm
------ ----- -------------------
S071 48166 2022-11-21 14:00:00
S071 48196 2022-11-21 14:00:00
S071 48228 2022-11-21 14:00:00
결과를 보면 Shop 테이블에는 두 매장(S070, S071)의 데이터가 존재하지만, Ord 테이블에는 S071 매장의 주문만 존재한다. 우선 두 데이터 집합을 지금까지 해온 것처럼 이너 조인으로 처리해보자. 당연히 조인 조건에 만족하지 못하는 S070 매장 정보는 사라지게 된다.
-- [SQL-7-9-3] Shop과 Ord를 INNER JOIN
SELECT T1.ShopId ,T1.ShopNm, T2.ShopId ,T2.OrdNo ,T2.OrdDtm
FROM startdb.Shop T1
INNER JOIN startdb.Ord T2
ON (T2.ShopId = T1.ShopId)
WHERE T1.ShopId IN ('S070','S071')
AND T2.ShopId IN ('S070','S071')
AND T2.OrdDtm >= STR_TO_DATE('20221121','%Y%m%d')
AND T2.OrdDtm <= STR_TO_DATE('20221122','%Y%m%d')
ORDER BY T1.ShopId;
ShopId ShopNm ShopId OrdNo OrdDtm
------ ---------- ------ ----- -------------------
S071 Austin-4th S071 48166 2022-11-21 14:00:00
S071 Austin-4th S071 48196 2022-11-21 14:00:00
S071 Austin-4th S071 48228 2022-11-21 14:00:00
이번에는 아우터 조인으로 변경해서 실행해보자. ‘INNER JOIN’ 이라고 작성했던 부분을 ‘LEFT OUTER JOIN’으로 변경하고, Ord 테이블에 대한 필터 조건(ShopId와 OrdDtm에 대한 조건)을 WHERE 절이 아닌 ON 절로 옮겨 적으면 된다.다음과 같다.
-- [SQL-7-9-4] Shop과 Ord를 OUTER JOIN
SELECT T1.ShopId ,T1.ShopNm
,T2.ShopId ,T2.OrdNo ,T2.OrdDtm
FROM startdb.Shop T1
LEFT OUTER JOIN startdb.Ord T2
ON (T2.ShopId = T1.ShopId
AND T2.ShopId IN ('S070','S071') -- > 조인 조건과 같은 조건이므로 생략 가능
AND T2.OrdDtm >= STR_TO_DATE('20221121','%Y%m%d')
AND T2.OrdDtm <= STR_TO_DATE('20221122','%Y%m%d'))
WHERE T1.ShopId IN ('S070','S071')
ORDER BY T1.ShopId;
ShopId ShopNm ShopId OrdNo OrdDtm
------ ------------ ------ ----- -------------------
S070 San Jose-4th NULL NULL NULL
S071 Austin-4th S071 48228 2022-11-21 14:00:00
S071 Austin-4th S071 48196 2022-11-21 14:00:00
S071 Austin-4th S071 48166 2022-11-21 14:00:00
이너 조인에서 사라졌던 S070 매장의 데이터가 아우터 조인 결과에는 포함되어 있는 것을 알 수 있다. S070 매장에 대한 Shop 테이블의 정보(ShopId, ShopNm)는 결과에 포함되어 있고, Ord 테이블의 정보(ShopId, OrdNo, OrdDtm)는 NULL로 채워져 있다.