CROSS JOIN


크로스 조인(CROSS JOIN)은 조인 조건이 없는 조인이다. 조인 조건이 없다는 것은 조인에 참여하는 두 테이블의 레코드 간에 조인 조건을 무조건 만족한다는 뜻이다. 크로스 조인은 카테시안 조인(CARTESIAN JOIN)이라고도 한다. 크로스 조인의 특징을 정리하면 다음과 같다.

Tip. OLTP VS. OLAP OLTP (Online Transaction Processing)는 주로 데이터 입력, 수정, 삭제등을 수행하는 시스템으로, 은행의 계좌이체, 쇼핑몰의 주문 처리등이 이해 속한다. OLAP (Online Analytical Processing)는 분석을 위한 시스템으로 대량의 데이터에 대해 복잡한 분석등을 주로 수행하는 시스템이다. 실제 목적에 맞게 OLTP와 OLAP를 구분해 데이터베이스를 구성하는 것이 좋지만 비용의 한계로 인해 OLTP 시스템에 몇 개의 분석 리포트를 추가하는 식으로 시스템을 구현하는 방식이 제법 많다.

아래와 같이 Shop과 Member를 각각 조회해서 데이터를 살펴본 후에, Shop과 Member를 크로스 조인 해보자. Shop의 S004가 Member의 모든 데이터와 조인이 이루어지고, S017도 Member의 모든 데이터와 조인이 이루어진 것을 알 수 있다.

-- [SQL-7-11-1] Shop 데이터 조회, 두 건의 매장이 조회된다.
SELECT  T1.ShopId ,T1.ShopNm
FROM    startdb.Shop T1
WHERE   T1.ShopId IN ('S004','S017');

ShopId  ShopNm            
------  ----------------  
S004    Houston-1st       
S017    Indianapolis-1st 

-- [SQL-7-11-2] Member 데이터 조회, 세 건의 회원이 조회된다.
SELECT  T2.MemberId ,T2.NickNm
FROM    startdb.Member T2
WHERE   T2.MemberId IN ('M1267','M1279','M1290');

MemberId  NickNm   
--------  -------  
M1267     Gold25   
M1279     Ocean25  
M1290     Spark25 

-- [SQL-7-11-3]
-- 두 건의 매장과 세 건의 회원을 CROSS JOIN
-- 2 x 3인 여섯 건의 결과가 만들어진다.
SELECT  T1.ShopId ,T1.ShopNm, T2.MemberId ,T2.NickNm
FROM    startdb.Shop T1
        CROSS JOIN startdb.Member T2
WHERE   T1.ShopId IN ('S004','S017')
AND     T2.MemberId IN ('M1267','M1279','M1290')
ORDER BY T1.ShopID ,T2.MemberId;

ShopId  ShopNm            MemberId  NickNm   
------  ----------------  --------  -------  
S004    Houston-1st       M1267     Gold25   
S004    Houston-1st       M1279     Ocean25  
S004    Houston-1st       M1290     Spark25  
S017    Indianapolis-1st  M1267     Gold25   
S017    Indianapolis-1st  M1279     Ocean25  
S017    Indianapolis-1st  M1290     Spark25 

크로스 조인은 조인에 참여하는 두 데이터 집합(WHERE 절의 필터 조건을 거친 데이터 집합)의 건수를 곱한만큼의 결과 건수가 만들어진다. 아래 두 데이터 집합을 크로스 조인하면 몇 건의 결과가 만들어질지 말해보자.

-- [SQL-7-11-4] 상품 조회
SELECT  T1.ItemId ,T1.ItemNm
FROM    startdb.Item T1
WHERE   T1.ItemCat = 'BEV'
AND     T1.LaunchDt = STR_TO_DATE('20190101','%Y%m%d');

ItemId  ItemNm            
------  ----------------  
HCHB    Hot Chocolate(B)  
HCHR    Hot Chocolate(R)  
LEMR    Lemonade(R)       

-- [SQL-7-11-5] 회원 조회
SELECT  T2.MemberId ,T2.NickNm ,T2.JoinDtm
FROM    startdb.Member T2
WHERE   T2.JoinDtm >= STR_TO_DATE('20220418','%Y%m%d')
AND     T2.JoinDtm <  STR_TO_DATE('20220420','%Y%m%d')
ORDER BY T2.JoinDtm;

MemberId  NickNm    JoinDtm              
--------  --------  -------------------  
M3168     Green63   2022-04-18 00:00:00  
M3166     Galaxy63  2022-04-19 00:00:00  
M3171     Leaf63    2022-04-19 00:00:00 

-- [SQL-7-11-6] 두 집합을 크로스 조인, 몇 건의 결과가 나올까?
SELECT  T1.ItemId ,T1.ItemNm
        ,T2.MemberId ,T2.NickNm ,T2.JoinDtm
FROM    startdb.Item T1
        CROSS JOIN startdb.Member T2
WHERE   T1.ItemCat = 'BEV'
AND     T1.LaunchDt = STR_TO_DATE('20190101','%Y%m%d')
AND     T2.JoinDtm >= STR_TO_DATE('20220418','%Y%m%d')
AND     T2.JoinDtm <  STR_TO_DATE('20220420','%Y%m%d')
ORDER BY T1.ItemId ,T2.MemberId;

크로스 조인을 사용할 일이 많지는 않다. 특히 OLTP 시스템에서는 사용될 가능성이 더욱 적다. 크로스 조인은 데이터 분석이나 리포트 작업에서 가끔 사용된다. 이러한 부분의 사용법은 뒤에서 다루게 될 것이다. 지금은 조인 조건 없이, 조인에 참여하는 데이터 집합의 레코드를 모두 조인시키는 크로스 조인이 있다는 것만 기억하도록 하자.

의도하지 않은 CROSS JOIN