OUTER JOIN 이해하기


아우터 조인(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로 채워져 있다.