UNION(=UNION DISTINCT)을 써야 할까?UNION은 여러 SELECT 결과를 세로로 합칠 때 “중복 행을 제거해야” 쓰는 연산자.
기본 가이드: 기본은 UNION ALL → 정말 중복 제거가 필요할 때만 UNION.
UNION이 맞는 대표 상황1) 파티션/소스가 겹쳐 중복 가능성이 높은 데이터를 합칠 때
SELECT * FROM sales_2022_03
UNION
SELECT * FROM sales_2022_04; -- 3/31, 4/1 중복 가능 → UNION으로 dedup
2) 동일 엔티티가 여러 테이블에 중복 저장되어 있을 때
예: 이벤트 참여 내역이 mobile_events, web_events 모두에 기록될 수 있음.
SELECT user_id FROM mobile_events
UNION
SELECT user_id FROM web_events; -- 유저 목록을 “중복 없이” 보고 싶을 때
3) 고유 목록/마스터 목록을 만들 때
예: 제품 카탈로그를 서로 다른 소스에서 모을 때 “한 번만” 보이도록.
SELECT product_id FROM products_source_a
UNION
SELECT product_id FROM products_source_b;
4) Distinct Top-N 후보군을 합쳐서 중복 제거 후 순위 매기기
예: 서로 다른 기준의 Top 추천 아이템을 합쳐 고유 후보군만 남기기.
SELECT item_id FROM top_by_ctr
UNION
SELECT item_id FROM top_by_conversion;
채널이 달라도 각각의 행이 모두 의미 있는 거래/로그일 때
→ 중복 제거하면 안 됨 → UNION ALL이 정답
가로 결합(속성 붙이기)가 목적일 때
→ JOIN이 정답, UNION 아님
집계나 중복 제거를 이미 완료한 결과를 다시 합칠 때
→ 보통 UNION ALL로 충분
세로 결합이 맞나?
맞다 → UNION/UNION ALL 후보
아니다(가로 결합) → JOIN
중복 행을 제거해야 하나? (비즈니스적으로 같은 행을 하나로 취급?)
예 → UNION
아니오 → UNION ALL
중복 판단 기준이 “행 전체”로 충분한가?
예 → UNION
아니오(특정 컬럼 기준 고유화 필요) → UNION ALL + 바깥에서 SELECT DISTINCT 컬럼들 ...
실전 패턴 스니펫
A) 파티션 월 테이블 합치기(중복 제거 필요)
SELECT order_id, order_date, user_id
FROM orders_2022_03
UNION
SELECT order_id, order_date, user_id
FROM orders_2022_04;
B) 채널별 로그 통합(중복 제거 불필요 → ALL)
SELECT ts, user_id, event FROM events_web
UNION ALL
SELECT ts, user_id, event FROM events_app;
C) 서로 다른 조인 결과를 한 화면에서 “중복 없이” 보여주기
SELECT user_id FROM premium_users
UNION
SELECT user_id FROM trial_users;
D) 특정 컬럼 기준으로만 고유화(행 전체가 아님)
SELECT DISTINCT user_id
FROM (
SELECT user_id FROM src_a
UNION ALL
SELECT user_id FROM src_b
) t;
컬럼 개수·순서·타입을 양쪽 SELECT에서 동일하게 맞추기
(필요하면 CAST, NULL AS col로 보정)
정렬은 마지막에 한 번만
→ DB에 따라 ORDER BY는 전체 결과에만 허용
성능: UNION은 내부적으로 DISTINCT(정렬/해시)를 수행 → 비용↑
→ 중복 제거가 필요 없으면 반드시 UNION ALL
기본은 UNION ALL.
“중복을 제거해야 의미가 맞다”면 그때만 UNION.