현재 선택한 SQL 과정

SQLP 이론 학습

이론 목록으로 돌아가기

집합 연산자: UNION·INTERSECT·MINUS

여러 SELECT 결과를 행 단위로 결합하며 중복 제거와 정렬 비용, 컬럼 호환 조건을 익힌다.

예상 읽기 6

핵심 요약

여러 SELECT 결과를 행 단위로 결합하며 중복 제거와 정렬 비용, 컬럼 호환 조건을 익힌다.

핵심 질문

  1. 집합 연산자: UNION·INTERSECT·MINUS에서 반드시 구분해야 할 개념과 결과 규칙은 무엇인가?
  2. 0건·1건·여러 건과 NULL·동점·중복 데이터에서 결과가 어떻게 달라지는가?
  3. 비슷해 보이는 문법과 결과가 같아지는 조건, 달라지는 조건은 무엇인가?
  4. 작은 샘플 데이터를 이용해 결과를 실수 없이 예측하는 순서는 무엇인가?

학습 목표

  • UNION·UNION ALL·INTERSECT·MINUS의 결과를 예측한다.
  • 집합 연산이 가능한 SELECT 목록 조건을 설명한다.

개념 지도

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
각 SELECT의 컬럼 수·타입 정렬 → 집합 결합 → 중복 제거 여부 → 최종 ORDER BY

핵심 내용

집합 연산자는 두 질의 결과를 세로로 결합한다.

연산자결과중복
UNION ALL양쪽 결과 모두유지
UNION합집합제거
INTERSECT교집합제거
MINUS왼쪽에서 오른쪽을 뺀 차집합제거

각 SELECT는 컬럼 수가 같고 같은 위치의 데이터 타입 그룹이 호환되어야 한다. 최종 컬럼명은 첫 SELECT의 별칭을 기준으로 이해하고, 전체 정렬은 마지막에 한 번 작성한다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT customer_id AS id FROM online_order
UNION ALL
SELECT customer_id FROM store_order
ORDER BY id;

중복 제거가 필요하지 않다면 UNION ALL이 불필요한 정렬·해시 작업을 피할 수 있다. 그러나 업무적으로 중복 제거가 필요하면 성능만을 이유로 바꾸면 결과가 달라진다.

흔한 오해와 주의점

  • 집합 연산은 열을 붙이는 조인과 달리 행을 이어 붙인다.
  • 연산자가 섞인 식은 우선순위 변경 가능성과 가독성을 고려해 괄호로 의도를 명확히 한다.
  • NULL도 중복 제거 과정에서는 같은 그룹으로 취급될 수 있다.

문항 풀이 보강: 집합 연산의 괄호와 동치

SQL Server의 EXCEPT는 Oracle의 MINUS와 같은 방향의 차집합이다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT a, b FROM tab1
EXCEPT
SELECT a, b FROM tab2;

이는 복합키 (a,b) 전체가 같은 TAB2 행이 존재하지 않는 TAB1 행을 찾는 NOT EXISTS로 바꿀 수 있다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
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은 두 배가 된다.

작은 집합으로 결과 계산하기

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
A = {1, 1, 2, 3}
B = {2, 3, 4}
연산결과
A UNION ALL B1, 1, 2, 3, 2, 3, 4
A UNION B1, 2, 3, 4
A INTERSECT B2, 3
A MINUS B1

MINUS는 방향이 있으므로 B MINUS A는 4가 된다. 집합 연산의 중복 제거는 전체 Row 조합을 기준으로 한다.

타입과 ORDER BY

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
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이 안전한 대안이 된다.


결과를 검증하는 순서

  1. 각 Query Block이 만드는 한 행의 의미를 먼저 적습니다.
  2. 조건을 적용하기 전 원본 행과 적용 후 남는 행을 작은 표로 그립니다.
  3. NULL 비교가 TRUE, FALSE, UNKNOWN 중 무엇인지 구분합니다.
  4. 중복 제거, 그룹화, 정렬과 행 제한이 적용되는 순서를 확인합니다.
  5. 데이터가 0건·1건·여러 건일 때도 같은 규칙이 성립하는지 검증합니다.

실무와 시험에서 함께 확인할 항목

  • ORDER BY가 없다면 결과 순서를 가정하지 않습니다.
  • 문자열·숫자·날짜 비교에서는 데이터 타입과 명시적 형변환을 확인합니다.
  • 같은 결과처럼 보이는 SQL도 NULL과 중복이 있을 때 달라질 수 있습니다.
  • 문법을 외우기 전에 샘플 데이터 3~5행으로 결과를 직접 계산합니다.

마지막 점검

  • 작성 순서가 아니라 SQL의 논리적 처리 순서로 결과를 계산합니다.
  • NULL을 0이나 빈 값과 같은 것으로 취급하지 않습니다.
  • ORDER BY가 없는 결과 순서와 DISTINCT 없는 중복 제거를 가정하지 않습니다.
  • 비슷한 문법은 0건·다건·NULL 데이터를 넣어 결과가 정말 같은지 확인합니다.

복습 문제

  1. 중복을 보존하는 합집합 연산자는?
  2. 두 SELECT의 컬럼 이름까지 같아야 하는가?
  3. 샘플 데이터 3행으로 결과를 직접 계산할 수 있는가?
  4. NULL이 포함될 때 결과가 달라지는 지점은 어디인가?