핵심 요약
여러 SELECT 결과를 행 단위로 결합하며 중복 제거와 정렬 비용, 컬럼 호환 조건을 익힌다.
학습 목표
- UNION·
UNION ALL· INTERSECT· MINUS의 결과를 예측한다. - 집합 연산이 가능한 SELECT 목록 조건을 설명한다.
본문
개념 지도
각 SELECT의 컬럼 수·타입 정렬→집합 결합→중복 제거 여부→최종 ORDER BY핵심 내용
집합 연산자는 두 질의 결과를 세로로 결합한다.
| 연산자 | 결과 | 중복 |
|---|---|---|
UNION ALL | 양쪽 결과 모두 | 유지 |
UNION | 합집합 | 제거 |
INTERSECT | 교집합 | 제거 |
MINUS | 왼쪽에서 오른쪽을 뺀 차집합 | 제거 |
각 SELECT는 컬럼 수가 같고 같은 위치의 데이터 타입 그룹이 호환되어야 한다. 최종 컬럼명은 첫 SELECT의 별칭을 기준으로 이해하고, 전체 정렬은 마지막에 한 번 작성한다.
SELECT customer_id AS id FROM online_order
UNION ALL
SELECT customer_id FROM store_order
ORDER BY id;
중복 제거가 필요하지 않다면 UNION ALL이 불필요한 정렬·해시 작업을 피할 수 있다. 그러나 업무적으로 중복 제거가 필요하면 성능만을 이유로 바꾸면 결과가 달라진다.
작은 집합으로 결과 계산하기
A = {1, 1, 2, 3}
B = {2, 3, 4}
| 연산 | 결과 |
|---|---|
A UNION ALL B | 1, 1, 2, 3, 2, 3, 4 |
A UNION B | 1, 2, 3, 4 |
A INTERSECT B | 2, 3 |
A MINUS B | 1 |
MINUS는 방향이 있으므로 B MINUS A는 4가 된다. 집합 연산의 중복 제거는 전체 Row 조합을 기준으로 한다.
타입과 ORDER BY
SELECT employee_id AS id, hire_date AS dt FROM employee
UNION ALL
SELECT customer_id, created_at FROM customer
ORDER BY id;
각 위치의 데이터 타입 그룹이 호환되어야 하고 최종 Column 이름은 첫 SELECT를 기준으로 한다. Branch별 ORDER BY는 일반적인 최종 결과 순서를 보장하지 않으므로 전체 집합 뒤에 한 번 작성한다. Branch 내부 Top-N이 필요하면 별도 Query Block으로 감싼다.
NULL과 집합 비교
집합 연산의 중복 제거에서는 같은 위치의 NULL을 중복 판단에 같은 값처럼 취급한다. 이는 NULL = NULL이 TRUE라는 뜻이 아니라 집합 중복 제거 규칙이다.
성능 판단
UNION, INTERSECT, MINUS는 Sort 또는 Hash로 중복·존재 비교 작업을 수행할 수 있다. 중복 제거가 업무상 필요 없을 때만 UNION ALL로 바꾼다. Branch가 상호 배타적임을 Predicate로 증명할 수 있으면 UNION ALL이 안전한 대안이 된다.
시험 포인트
SQL Server의 EXCEPT는 Oracle의 MINUS와 같은 방향의 차집합이다.
SELECT a, b FROM tab1
EXCEPT
SELECT a, b FROM tab2;
이는 복합키 (a,b) 전체가 같은 TAB2 행이 존재하지 않는 TAB1 행을 찾는 NOT EXISTS로 바꿀 수 있다.
SELECT t1.a, t1.b
FROM tab1 t1
WHERE NOT EXISTS (
SELECT 1
FROM tab2 t2
WHERE t2.a = t1.a
AND t2.b = t1.b
);
UNION은 전체 결과 행 조합의 중복을 제거하고, UNION ALL은 보존한다. 첫 SELECT의 별칭이 최종 컬럼 이름이 되며 ORDER BY 1,2는 최종 SELECT 목록 위치를 뜻한다.
1:1 양쪽 필수 관계가 보장되면 두 테이블의 키 집합은 같다. 이때 INTERSECT 결과와 키 조인 결과 건수는 같고, EXCEPT는 공집합이며, UNION은 한 집합 크기지만 UNION ALL은 두 배가 된다.
자주 틀리는 부분
- 집합 연산은 열을 붙이는 조인과 달리 행을 이어 붙인다.
- 연산자가 섞인 식은 우선순위 변경 가능성과 가독성을 고려해 괄호로 의도를 명확히 한다.
- NULL도 중복 제거 과정에서는 같은 그룹으로 취급될 수 있다.
복습 문제
답을 생각한 뒤 정답과 근거를 펼쳐 보세요.
중복을 보존하는 합집합 연산자는?
정답과 근거
UNION ALL이 중복을 보존합니다.
두 SELECT의 컬럼 이름까지 같아야 하는가?
정답과 근거
이름은 같을 필요가 없지만 컬럼 수와 위치별 데이터 타입이 호환되어야 합니다. 최종 이름은 첫 SELECT의 표현을 따릅니다.
UNION ALL과 UNION 중 어느 연산이 중복을 유지하며, 최종 정렬은 어느 Query Block에 적용하는가?
정답과 근거
UNION ALL은 중복을 유지하고 UNION은 중복을 제거합니다. 최종 ORDER BY는 집합 연산 전체 결과 뒤에 한 번 적용합니다.