집합연산자 완벽 정리
SQLD 시험 출제 범위의 UNION·UNION ALL·INTERSECT·MINUS를 예시와 함께 정리
1. 집합연산자 개요
집합연산자란?
집합연산자는 두 개 이상의 SELECT 결과를 결합하는 연산자입니다. 수학의 합집합, 교집합, 차집합 개념을 SQL에 적용한 것으로, JOIN 없이 여러 쿼리 결과를 하나로 합칠 수 있습니다.
집합연산자 종류
| 연산자 | 수학 개념 | 설명 | 중복 |
|---|---|---|---|
| UNION | 합집합 | 두 결과의 합 (중복 제거) | 제거 |
| UNION ALL | 합집합 | 두 결과의 합 (중복 포함) | 포함 |
| INTERSECT | 교집합 | 두 결과의 공통 부분 | 제거 |
| MINUS / EXCEPT | 차집합 | 첫 번째에만 있는 결과 | 제거 |
Oracle은 MINUS, SQL Server는 EXCEPT를 사용합니다.
예시 테이블
아래 두 쿼리 결과를 기준으로 각 연산자의 결과를 설명합니다.
쿼리 A 결과
| ID | NAME |
|---|---|
| 1 | 김철수 |
| 2 | 이영희 |
| 3 | 박민수 |
쿼리 B 결과
| ID | NAME |
|---|---|
| 2 | 이영희 |
| 3 | 박민수 |
| 4 | 최지은 |
2. UNION vs UNION ALL
UNION (중복 제거)
SELECT ID, NAME FROM TABLE_A
UNION
SELECT ID, NAME FROM TABLE_B;
두 결과의 합집합에서 중복 행을 제거합니다. 내부적으로 정렬(SORT) 작업이 발생합니다.
| ID | NAME |
|---|---|
| 1 | 김철수 |
| 2 | 이영희 |
| 3 | 박민수 |
| 4 | 최지은 |
결과: 4행 (중복된 이영희, 박민수 제거)
UNION ALL (중복 포함)
SELECT ID, NAME FROM TABLE_A
UNION ALL
SELECT ID, NAME FROM TABLE_B;
중복 제거 없이 모든 행을 그대로 합칩니다. 정렬 작업이 없으므로 UNION보다 성능이 좋습니다.
| ID | NAME |
|---|---|
| 1 | 김철수 |
| 2 | 이영희 |
| 3 | 박민수 |
| 2 | 이영희 |
| 3 | 박민수 |
| 4 | 최지은 |
결과: 6행 (중복 포함)
UNION vs UNION ALL 비교
| 항목 | UNION | UNION ALL |
|---|---|---|
| 중복 | 제거 | 포함 |
| 정렬 | 내부적으로 정렬 발생 | 정렬 없음 |
| 성능 | 느림 (정렬 비용) | 빠름 |
중복이 없는 것이 확실하면 UNION ALL을 사용하는 것이 성능상 유리합니다.
3. INTERSECT (교집합)
개념 및 구문
두 SELECT 결과의 공통된 행만 반환합니다. 중복 행은 제거됩니다.
SELECT ID, NAME FROM TABLE_A
INTERSECT
SELECT ID, NAME FROM TABLE_B;
| ID | NAME |
|---|---|
| 2 | 이영희 |
| 3 | 박민수 |
결과: 2행 (양쪽 모두에 있는 행)
4. MINUS / EXCEPT (차집합)
개념 및 구문
첫 번째 SELECT 결과에서 두 번째 결과에 있는 행을 제외합니다. Oracle은 MINUS, SQL Server는 EXCEPT를 사용합니다.
-- Oracle
SELECT ID, NAME FROM TABLE_A
MINUS
SELECT ID, NAME FROM TABLE_B;
-- SQL Server
SELECT ID, NAME FROM TABLE_A
EXCEPT
SELECT ID, NAME FROM TABLE_B;
| ID | NAME |
|---|---|
| 1 | 김철수 |
결과: 1행 (A에만 있는 김철수)
순서에 따른 결과 차이
MINUS/EXCEPT는 순서가 중요합니다. A MINUS B와 B MINUS A의 결과가 다릅니다.
| 연산 | 결과 |
|---|---|
| A MINUS B | 1, 김철수 (A에만 있는 것) |
| B MINUS A | 4, 최지은 (B에만 있는 것) |
5. 집합연산자 사용 규칙
필수 규칙
- 1. SELECT 컬럼 수가 동일해야 함 — 첫 번째와 두 번째 SELECT의 컬럼 수가 같아야 함
- 2. 대응 컬럼의 데이터 타입이 호환되어야 함 — 같은 위치의 컬럼끼리 타입이 일치하거나 자동 변환 가능해야 함
- 3. ORDER BY는 마지막 SELECT에만 사용 — 최종 결과 전체에 대한 정렬이므로 맨 마지막에 1번만 작성
- 4. 컬럼명은 첫 번째 SELECT 기준 — 결과의 컬럼 헤더는 첫 번째 SELECT의 컬럼명(또는 별칭)을 따름
- 5. ORDER BY에는 첫 번째 SELECT의 컬럼명 사용 — 또는 컬럼 순서 번호(1, 2, 3...)를 사용 가능
ORDER BY 위치 예시
-- 올바른 사용
SELECT ID, NAME FROM TABLE_A
UNION
SELECT ID, NAME FROM TABLE_B
ORDER BY ID; -- 마지막에 1번만
-- 잘못된 사용
SELECT ID, NAME FROM TABLE_A ORDER BY ID -- 에러!
UNION
SELECT ID, NAME FROM TABLE_B;
6. 집합연산자 조합 활용
여러 집합연산자 조합
집합연산자는 위에서 아래로 순차적으로 처리됩니다. 괄호로 우선순위를 지정할 수 있습니다 (Oracle에서만 지원).
SELECT ID FROM TABLE_A
UNION ALL
SELECT ID FROM TABLE_B
INTERSECT
SELECT ID FROM TABLE_C;
-- 처리 순서: 위에서 아래로
-- 1) A UNION ALL B
-- 2) (A UNION ALL B) INTERSECT C
집합연산자 vs JOIN vs 서브쿼리
| 집합연산자 | 동일한 효과의 다른 방법 |
|---|---|
| INTERSECT | INNER JOIN 또는 IN 서브쿼리 |
| MINUS / EXCEPT | NOT IN, NOT EXISTS, LEFT JOIN + IS NULL |
| UNION ALL | 대안 없음 (고유한 기능) |
7. 시험 빈출 포인트
반드시 알아야 할 포인트
- 1. UNION은 중복 제거, UNION ALL은 중복 포함 — 가장 기본적인 차이이자 최다 출제 포인트
- 2. UNION은 정렬 발생, UNION ALL은 정렬 없음 — 성능 면에서 UNION ALL이 유리
- 3. SELECT 컬럼 수와 타입 일치 필수 — 위치별로 컬럼 수가 같고 데이터 타입이 호환되어야 함
- 4. ORDER BY는 맨 마지막에 1번만 — 중간 SELECT에 ORDER BY를 쓰면 에러
- 5. 컬럼명은 첫 번째 SELECT 기준 — 두 번째 SELECT에 별칭을 써도 무시됨
- 6. Oracle = MINUS, SQL Server = EXCEPT — 기능은 동일하지만 키워드가 다름
- 7. MINUS/EXCEPT는 순서가 중요 — A MINUS B와 B MINUS A의 결과가 다름
- 8. INTERSECT는 INNER JOIN과 유사한 결과 — 교집합은 양쪽 모두에 존재하는 데이터만 반환
- 9. NULL 처리 — 집합연산자에서 NULL끼리는 같은 것으로 처리 (일반 비교와 다름!)
- 10. 결과 행 수 계산 문제 — UNION, UNION ALL, INTERSECT, MINUS 결과 행 수를 물어보는 문제 빈출
개념을 확인했다면 문제로 실력을 검증해보세요