조인은 데이터 집합을 좌우로 연결한다. 반면에 UNION ALL은 데이터 집합을 상하로 연결한다.
아래는 UNION ALL을 사용해 매장 건수와 회원 건수, 상품 건수를 보여주는 SQL이다. 조인과 다르게 데이터 집합을 연결하는 조건을 고려하지 않아도 된다. UNION ALL로 연결 할 데이터 집합의 컬럼 수만 잘 맞추면 된다.
-- [SQL-7-12-1]
SELECT 'Shop' DV, COUNT(*) Cnt
FROM startdb.Shop T1
UNION ALL
SELECT 'Member' DV, COUNT(*) Cnt
FROM startdb.Member T2
UNION ALL
SELECT 'Item' DV, COUNT(*) Cnt
FROM startdb.Item T3;
DV Cnt
------ ----
Shop 300
Member 9999
Item 21
UNION ALL을 사용할 때는 다음의 내용을 주의해야 한다.
아래는 주문년월별 주문금액과 주문건수를 보여주는 SQL이다.
-- [SQL-7-12-2]
SELECT DATE_FORMAT(T1.OrdDtm,'%Y%m') OrdYm
,SUM(OrdAmt) OrdAmt
,COUNT(*) OrdCnt
FROM startdb.Ord T1
WHERE T1.OrdDtm >= STR_TO_DATE('20210101','%Y%m%d')
AND T1.OrdDtm < STR_TO_DATE('20210401','%Y%m%d')
GROUP BY DATE_FORMAT(T1.OrdDtm,'%Y%m');
OrdYm OrdAmt OrdCnt
------ ----------- ------
202101 2590000.000 501
202102 3154500.000 610
202103 3858000.000 746
위 SQL의 결과를 보면 년월별로 주문금액과 주문건수가 각각의 컬럼으로 출력되고 있다. 위와 같은 결과를 아래와 같이 변형해보려고 한다. 주문금액과 주문건수를 컬럼이 아닌 로우로 분리하려고 하는 것이다.
OrdYm VAL_Nm VAL
------ ------ -----------
202101 AMT 2590000.000
202102 AMT 3154500.000
202103 AMT 3858000.000
202101 CNT 501.000
202102 CNT 610.000
202103 CNT 746.000
위와 같은 결과는 UNION ALL을 활용하면 쉽게 구할 수 있다. 년월별 주문금액 SQL과 년월별 주문건수 SQL을 각각 구해서 UNION ALL 처리하면 된다. 아래와 같다.
-- [SQL-7-12-3]
SELECT DATE_FORMAT(T1.OrdDtm,'%Y%m') OrdYm
,'AMT' VAL_Nm
,SUM(OrdAmt) VAL
FROM startdb.Ord T1
WHERE T1.OrdDtm >= STR_TO_DATE('20210101','%Y%m%d')
AND T1.OrdDtm < STR_TO_DATE('20210401','%Y%m%d')
GROUP BY DATE_FORMAT(T1.OrdDtm,'%Y%m')
UNION ALL
SELECT DATE_FORMAT(T1.OrdDtm,'%Y%m') OrdYm
,'CNT' VAL_Nm
,COUNT(*) OrdCnt
FROM startdb.Ord T1
WHERE T1.OrdDtm >= STR_TO_DATE('20210101','%Y%m%d')
AND T1.OrdDtm < STR_TO_DATE('20210401','%Y%m%d')
GROUP BY DATE_FORMAT(T1.OrdDtm,'%Y%m');