DBAtlas · 데이터베이스 운영 아틀라스

UNION / UNION ALL / INTERSECT / EXCEPT(MINUS)

Oracle

-- Union without duplicates
SELECT city FROM customer
UNION
SELECT city FROM supplier;

-- Intersection and difference (MINUS instead of EXCEPT in Oracle)
SELECT city FROM customer INTERSECT SELECT city FROM supplier;
SELECT city FROM customer MINUS SELECT city FROM supplier;

집합 연산자는 두 쿼리의 결과 집합을 결합한다. UNION은 중복을 제거하고(더 느림), UNION ALL은 모두 유지하며(더 빠름), INTERSECT는 공통 행을, 차집합 연산자는 첫 번째 집합에만 있는 행을 반환한다. Oracle은 차집합에 표준 EXCEPT 대신 MINUS를 사용한다(21c부터 EXCEPT도 있음).

PostgreSQL

SELECT city FROM customer
UNION
SELECT city FROM supplier;

SELECT city FROM customer INTERSECT SELECT city FROM supplier;
SELECT city FROM customer EXCEPT SELECT city FROM supplier;

PostgreSQL은 표준 UNION, UNION ALL, INTERSECT, EXCEPT를 완전히 지원한다(차집합은 MINUS가 아닌 EXCEPT). 각 연산자의 ALL 형식(INTERSECT ALL, EXCEPT ALL)은 중복 개수를 보존한다. 컬럼 수와 타입이 호환되어야 한다.

MySQL

SELECT city FROM customer
UNION
SELECT city FROM supplier;

-- INTERSECT/EXCEPT arrive with MySQL 8.0.31+ and MariaDB 10.3+
SELECT city FROM customer INTERSECT SELECT city FROM supplier;

MySQL은 오랫동안 UNION / UNION ALL만 지원했으며, INTERSECT와 EXCEPT는 MySQL 8.0.31(MariaDB 10.3)에서야 추가되었다. 이전 버전에서는 교집합에 INNER JOIN/EXISTS를, 차집합에 LEFT JOIN ... IS NULL 또는 NOT EXISTS를 사용한다.

SQL Server

SELECT city FROM customer
UNION
SELECT city FROM supplier;

SELECT city FROM customer INTERSECT SELECT city FROM supplier;
SELECT city FROM customer EXCEPT SELECT city FROM supplier;

SQL Server는 표준 UNION, UNION ALL, INTERSECT, EXCEPT(2005+)를 지원하며, 차집합 연산자는 EXCEPT다(MINUS 아님). INTERSECT/EXCEPT는 NULL 값을 같은 값으로 취급해 행을 비교한다.

MongoDB

// Closest equivalent: $unionWith (MongoDB 4.4+)
db.customer.aggregate([
  { $project: { city: 1, _id: 0 } },
  { $unionWith: { coll: "supplier",
      pipeline: [ { $project: { city: 1, _id: 0 } } ] } },
  { $group: { _id: "$city" } }  // UNION (distinct) effect
])

MongoDB 4.4+의 $unionWith 단계는 두 컬렉션의 결과를 결합한다(UNION ALL과 유사). 중복을 제거하려면 이후 $group으로 중복을 제거한다. INTERSECT/EXCEPT는 직접 대응하는 기능이 없으며 $lookup이나 집합 연산자($setIntersection, $setDifference)로 모델링한다.

Redis

# Set operations with the Set data type:
SUNION city_customer city_supplier    # union
SINTER city_customer city_supplier    # intersection
SDIFF  city_customer city_supplier    # difference

Redis에는 SQL이 없지만 Set 데이터 타입이 네이티브 집합 연산을 제공한다: SUNION(합집합), SINTER(교집합), SDIFF(차집합)과 결과를 저장하는 STORE 변형. 이 연산은 쿼리 결과가 아니라 미리 구성된 집합 멤버에 대해 동작한다.

Elasticsearch

# There is no direct set operator.
# For a union, search multiple indices in one query:
GET customer,supplier/_search
{ "query": { "match_all": {} } }

Elasticsearch는 UNION/INTERSECT/EXCEPT를 제공하지 않는다. 합집합 효과는 쉼표로 구분한 여러 인덱스를 조회해 얻고, 교집합과 차집합은 bool 쿼리의 must/should/must_not 절이나 애플리케이션 측 집합 로직으로 처리한다.

DBAtlas에서 열기 →