[SQLD] 07. 집합 연산자 (Set Operators)

TJK·2025년 7월 29일
1

집합 연산자 (Set Operators)

집합 연산자는 두 개 이상의 SELECT 문의 결과 집합을 수직으로 연결하여 하나의 통합된 결과 집합으로 만드는 데 사용됨. JOIN이 테이블을 수평으로 연결하는 것과는 대조적임.


1. 집합 연산자 사용 규칙

집합 연산자를 사용하기 위해서는 합치려는 모든 SELECT 문이 다음의 규칙을 준수해야 함.

  • 컬럼 개수 일치: 모든 SELECT 문의 조회 컬럼 개수가 동일해야 함.
  • 데이터 타입 호환: 각 SELECT 문의 대응되는 위치의 컬럼들은 서로 호환 가능한 데이터 타입을 가져야 함. (예: NUMBERNUMBER, VARCHAR2CHAR)
  • 컬럼명 기준: 최종 결과의 컬럼명은 첫 번째 SELECT 문의 컬럼명(또는 별칭)을 따라감.
  • ORDER BY 절 위치: 정렬이 필요한 경우, ORDER BY 절은 가장 마지막 SELECT 문 뒤에 한 번만 사용해야 함.

2. 주요 집합 연산자

연산자설명중복 제거자동 정렬
UNION ALL두 결과 집합을 그대로 합침.❌ (중복 허용)
UNION두 결과 집합의 합집합을 구함.
INTERSECT두 결과 집합의 교집합을 구함.
MINUS두 결과 집합의 차집합을 구함. (첫 번째 결과 - 두 번째 결과)

2.1. UNION ALL (합집합, 중복 포함)

  • SELECT 문의 결과를 단순히 이어 붙임.
  • 중복 제거 및 정렬 과정이 없으므로, 네 가지 연산자 중 성능이 가장 빠름.
  • 데이터의 발생 순서나 로그 등을 그대로 합쳐 볼 때 유용함.
/*
 * -- UNION ALL 예시: 모든 활동 사용자 ID 목록 조회 --
 * '좋아요'를 누른 사용자 목록과 '댓글'을 작성한 사용자 목록을
 * 중복에 상관없이 모두 합쳐서 조회함.
 */
SELECT user_id FROM Likes
UNION ALL
SELECT user_id FROM Comments;

2.2. UNION (합집합, 중복 제거)

  • SELECT 문의 결과를 합치면서 중복된 행은 제거함.
  • 중복 제거를 위해 내부적으로 정렬 작업을 수행하므로 UNION ALL보다 성능 부담이 있음.
  • 순수한 '활동 사용자' 목록처럼 고유한 목록을 얻을 때 사용함.
/*
 * -- UNION 예시: 순수 활동 사용자 ID 목록 조회 --
 * '좋아요' 또는 '댓글'을 작성한 모든 사용자의 ID를 중복 없이 조회함.
 * 결과는 기본적으로 오름차순 정렬됨.
 */
SELECT user_id FROM Likes
UNION
SELECT user_id FROM Comments;

2.3. INTERSECT (교집합)

  • SELECT 문의 결과에 모두 공통으로 존재하는 행만 반환함.
  • '열성 유저'와 같이 두 가지 이상의 활동을 모두 한 대상을 찾을 때 유용함.
/*
 * -- INTERSECT 예시: 열성 사용자 ID 목록 조회 --
 * '좋아요'도 누르고 '댓글'도 작성한 사용자의 ID를 조회함.
 */
SELECT user_id FROM Likes
INTERSECT
SELECT user_id FROM Comments;

2.4. MINUS (차집합)

  • 첫 번째 SELECT 문의 결과에서 두 번째 SELECT 문의 결과와 일치하는 행을 제외한 나머지를 반환함.
  • 연산의 순서가 중요함 (A MINUS BB MINUS A).
  • 특정 활동은 했지만 다른 활동은 하지 않은 대상을 찾을 때 유용함.
/*
 * -- MINUS 예시: '좋아요'만 누른 사용자 ID 목록 조회 --
 * '좋아요'를 누른 사용자 중에서, '댓글'을 작성한 사용자는 제외하고 조회함.
 */
SELECT user_id FROM Likes
MINUS
SELECT user_id FROM Comments;

※ DBMS별 문법 차이: MINUS는 Oracle에서 사용하는 키워드임. SQL Server와 PostgreSQL에서는 EXCEPT 키워드가 동일한 기능을 수행함. MySQL은 MINUSEXCEPT를 지원하지 않으므로, LEFT JOIN이나 NOT IN 등을 활용하여 차집합을 구현해야 함.


3. 심화 개념: 집합 연산자와 서브쿼리의 비교

INTERSECTMINUS는 각각 IN 서브쿼리와 NOT IN 서브쿼리로 유사하게 구현할 수 있음. 그러나 집합 연산자는 다음과 같은 장점을 가짐.

  • 가독성: A INTERSECT B 와 같이 개발자의 의도를 명확하고 직관적으로 표현함.
  • 성능: 대용량 데이터 처리 시, 옵티마이저가 집합 연산자를 더 효율적인 실행 계획으로 처리할 수 있음.
  • 엄격한 규칙: 컬럼 수와 타입이 일치해야 하므로, 데이터 정합성을 보장하고 예측 가능한 결과를 얻을 수 있음.

4. 시험 문제 유형 및 함정 포인트

  • UNION vs UNION ALL: 두 연산자의 가장 큰 차이인 중복 제거자동 정렬 여부를 묻는 문제가 가장 빈번하게 출제됨. 쿼리 결과의 행 수를 예측하는 유형으로 자주 나옴.
  • MINUS 연산의 순서: A MINUS BB MINUS A의 결과가 다르다는 점을 이용한 함정 문제가 출제될 수 있음.
  • 집합 연산자 규칙 위반: SELECT 문의 컬럼 개수나 데이터 타입이 다른 경우, 문법 오류가 발생한다는 점을 알고 있어야 함.
  • ORDER BY 위치: ORDER BY 절은 반드시 전체 문장의 맨 마지막에 와야 함. 중간 SELECT 문에 ORDER BY를 사용하면 오류가 발생함.
  • DBMS별 키워드 차이: MINUS(Oracle)와 EXCEPT(SQL Server)의 차이를 묻는 문제가 출제될 수 있음. SQLD는 Oracle 기반이므로 MINUS를 기준으로 학습하는 것이 유리함.
profile
Hello world!

0개의 댓글