SQL Server EXCEPT 연산자란?
SQL Server의 EXCEPT 연산자는 첫 번째 SELECT 문의 결과 집합에는 존재하지만 두 번째 SELECT 문의 결과 집합에는 없는 행만 반환하는 집합 연산자입니다. 각 SELECT 문은 하나의 데이터 집합을 생성하며, EXCEPT는 첫 번째 집합의 레코드를 가져온 뒤 두 번째 집합에 포함된 결과를 제거합니다.
EXCEPT 쿼리의 동작 원리
설명: 벤 다이어그램에서 파란색 영역에 해당하는 레코드, 즉 데이터 집합 1에는 있지만 데이터 집합 2에는 없는 레코드가 최종 결과로 반환됩니다.
EXCEPT 쿼리의 각 SELECT 문은 결과 집합에서 동일한 수의 필드를 가져야 하며, 서로 대응하는 열의 데이터 타입도 일치해야 합니다.
EXCEPT 연산자 기본 문법
SELECT 표현식1, 표현식2, ... 표현식n
FROM 테이블
[WHERE 조건]
EXCEPT
SELECT 표현식1, 표현식2, ... 표현식n
FROM 테이블
[WHERE 조건];
매개변수 설명
표현식(expression)
SELECT 문 사이에서 비교하려는 열 또는 값입니다. 각 SELECT 문에서 반드시 같은 필드일 필요는 없지만, 서로 대응되는 열의 데이터 타입은 동일해야 합니다.
테이블(table)
레코드를 조회할 테이블입니다. FROM 절에는 최소한 하나 이상의 테이블이 지정되어야 합니다.
WHERE 조건
선택 사항입니다. 조회 대상 레코드가 반드시 만족해야 하는 조건을 지정합니다.
사용 시 주의 사항
- 두 SELECT 문은 동일한 수의 표현식(열)을 포함해야 합니다.
- 각 SELECT 문에서 서로 대응하는 열은 데이터 타입이 같아야 합니다.
- EXCEPT 연산자는 첫 번째 SELECT 문의 레코드 중 두 번째 SELECT 문에 없는 모든 레코드를 반환합니다.
- SQL Server의 EXCEPT 연산자는 Oracle의 MINUS 연산자와 기능이 동일합니다.
예제 1 — 표현식이 하나인 경우
SELECT product_id
FROM products
EXCEPT
SELECT product_id
FROM inventory;
이 예제에서는 products(제품) 테이블에는 존재하지만 inventory(재고) 테이블에는 없는 모든 product_id 값이 반환됩니다. 즉, 두 테이블 모두에 존재하는 product_id 값은 결과에서 제외됩니다.
예제 2 — 여러 표현식을 사용하는 경우
SELECT contact_id, last_name, first_name
FROM contacts
WHERE last_name = 'Anderson'
EXCEPT
SELECT employee_id, last_name, first_name
FROM employees;
이 쿼리는 contacts(연락처) 테이블에서 성(last_name)이 'Anderson'인 레코드 중, employees(직원) 테이블의 직원 ID·성·이름과 일치하지 않는 레코드를 반환합니다.
예제 3 — ORDER BY 절 함께 사용하기
SELECT supplier_id, supplier_name
FROM suppliers
WHERE state = 'Florida'
EXCEPT
SELECT company_id, company_name
FROM companies
WHERE company_id <= 400
ORDER BY 2;
이 예제에서는 두 SELECT 문의 열 이름이 서로 다르기 때문에, ORDER BY 절에서 열 이름 대신 결과 집합 내의 위치를 지정해 정렬하는 것이 더 편리합니다. 위 쿼리는 ORDER BY 2를 사용해 결과 집합의 두 번째 열인 supplier_name / company_name을 오름차순으로 정렬합니다. supplier_name / company_name이 결과 집합에서 두 번째 위치에 있기 때문입니다.
추가 팁
EXCEPT는 기본적으로 중복된 행을 자동으로 제거하고 고유한(distinct) 결과만 반환합니다. 또한 UNION(합집합), INTERSECT(교집합)와 함께 SQL Server의 대표적인 집합 연산자이므로, 상황에 맞게 함께 활용하면 복잡한 데이터 비교 로직도 간결하게 작성할 수 있습니다.