CROSS JOIN
크로스 조인(CROSS JOIN)은 조인 조건이 없는 조인이다. 조인 조건이 없다는 것은 조인에 참여하는 두 테이블의 레코드 간에 조인 조건을 무조건 만족한다는 뜻이다. 크로스 조인은 카테시안 조인(CARTESIAN JOIN)이라고도 한다. 크로스 조인의 특징을 정리하면 다음과 같다.
•
조인에 참여하는 두 데이터 집합의 건수를 곱한 만큼의 건수가 결과로 만들어진다.
•
데이터 분석을 위해 주로 사용되는 기법이다. OLTP 환경에서는 잘 사용되지 않는다.
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
SQL
복사
크로스 조인은 조인에 참여하는 두 데이터 집합(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;
SQL
복사
크로스 조인을 사용할 일이 많지는 않다. 특히 OLTP 시스템에서는 사용될 가능성이 더욱 적다. 크로스 조인은 데이터 분석이나 리포트 작업에서 가끔 사용된다. 이러한 부분의 사용법은 뒤에서 다루게 될 것이다. 지금은 조인 조건 없이, 조인에 참여하는 데이터 집합의 레코드를 모두 조인시키는 크로스 조인이 있다는 것만 기억하도록 하자.
의도하지 않은 CROSS JOIN
조인을 작성할 때 주의가 필요하다. 의도치 않게 크로스 조인이 작동되는 경우가 있다. 아래 두 SQL은 모두 크로스 조인과 같은 조인 결과가 만들어진다.
-- [SQL-7-11-7] 조인 조건에서 같은 T2.OrdNo를 사용
SELECT T1.ShopId ,T1.ShopNm ,T2.OrdDtm ,T2.OrdNo
FROM startdb.Shop T1
INNER JOIN startdb.Ord T2
ON (T2.OrdNo = T2.OrdNo) -- > 조인 조건 컬럼에 모두 T2를 사용
WHERE T1.ShopId IN ('S004','S017')
AND T2.OrdDtm >= STR_TO_DATE('20220101','%Y%m%d')
AND T2.OrdDtm < STR_TO_DATE('20220201','%Y%m%d');
-- [SQL-7-11-8] 조인 조건을 실수로 생략
SELECT T1.ShopId ,T1.ShopNm ,T2.OrdDtm ,T2.OrdNo
FROM startdb.Shop T1
INNER JOIN startdb.Ord T2
-- > 실수로 ON 절을 생략
WHERE T1.ShopId IN ('S004','S017')
AND T2.OrdDtm >= STR_TO_DATE('20220101','%Y%m%d')
AND T2.OrdDtm < STR_TO_DATE('20220201','%Y%m%d');
SQL
복사
여러분들이 앞으로 최소한 한번 쯤은 하게될 실수 패턴이니 잘 기억해두고 주의하기 바란다. 이와 같은 실수로 건수가 많은 데이터 집합 간에 크로스 조인이 발생하면 시스템 장애로 이어질 수도 있다. 예를 들어 만 건과 만 건의 데이터가 크로스 조인하면 만들어지는 결과는 1억 건이 된다. 1억 건의 데이터를 만들어내기 위해서는 DBMS 내부적으로 많은 자원을 소모하게 된다. 조인 SQL을 작성했다면 실행 전에 자신이 조인 조건을 제대로 작성했는지 한 번 더 살펴보기 바란다.
Upper: 7. JOIN