[ 살펴보기 ] Sql - 집합 연산
![[ 살펴보기 ] Sql - 집합 연산](https://cdn.hashnode.com/res/hashnode/image/upload/v1720075206588/d3a5d835-583e-4fb7-b6ba-83a4b9732df3.jpeg)
Union, Intersect, Except 집합 연사자를 통해 두 테이블의 합집합에 해당하는 데이터, 교집합에 해당하는 데이터, 차집합에 해당하는 데이터를 조회할 수 있다
주의할 점은 집합 연산을 수행할 때는 조회하는 열의 수가 두 테이블에서 같아야 한다. 예를 들어 customer와 actor 테이블을 통해 집합 연산을 수행하고 있고 customer에서 first_name, last_name 두 가지 열을 조회한다면 나머지 테이블인 actor 테이블 또한 2개의 열을 조회해야 한다.
SELECT customer.first_name, customer.last_name /* 2 column 조회 */
FROM customer
UNION
SELECT actor.first_name, actor.last_name /* 2 column 조회 */
FROM actor
아래 Query는 조회하는 column 숫자가 맞지 않으므로 오류가 발생한다
SELECT customer.first_name, customer.last_name /* 2 column 조회 */
FROM customer
UNION
SELECT actor.first_name, actor.last_name, actor.actor_id /* 3 column 조회 */
FROM actor
/*
조회하는 column 수가 서로 다르므로 오류 발생
*/
Union, Union All
두 테이블을 결합시켜 데이터를 가지고 올 때 Union 명령을 통해 데이터를 조회한다. 다음 예제를 보자
SELECT customer.first_name, customer.last_name
FROM customer
WHERE customer.first_name like 'A%'
UNION
SELECT actor.first_name, actor.last_name
FROM actor
WHERE actor.first_name like "A%"
위의 예제는 customer 테이블과 actor 테이블 양쪽 모두에서 first_name이 A로 시작하는 조건으로 first name과 last name 데이터를 불러온다.

UNION 연산자만 사용했을 때는 중복되는 데이터가 자동으로 걸러지지만 만약 중복되는 데이터도 출력하고자 한다면 UNION 대신 UNION ALL 연산자를 사용한다.
Intersect
두 테이블 양쪽 모두에 존재하는 데이터인 교집합에 해당하는 데이터를 출력 한다. MySQL에서는 지원하지 않는다
SELECT customer.first_name, customer.last_name
FROM customer
INTERSECT
SELECT actor.first_name, actor.last_name
FROM actor
위의 예제는 customer 테이블과 actor 테이블 양쪽에 동일한 first_name과 last_name을 가진 데이터가 있으면 해당 데이터를 출력한다
Except
Except 연산자는 A와 B 테이블에 대해 집합 연산을 수행할 때 ( A EXCEPT B ) A 테이블 데이터 중 B 테이블에도 동일한 데이터가 있으면 해당 데이터를 제외한 나머지 A 테이블의 데이터를 출력한다, 즉 A 테이블에만 존재하는 데이터만 출력한다. MySQL에서는 지원하지 않는다
SELECT customer.first_name, customer.last_name
FROM customer
EXCEPT
SELECT actor.first_name, actor.last_name
FROM actor
위의 예제를 기준으로 customer table에만 존재하는 first name과 last name을 출력해준다
집합연산 순서
만약 UNION과 같은 집합 연산자가 한 개 이상 사용되고 있다면 보통 위에서 아래의 순서대로 실행된다. 하지만 ANSI SQL 사양에 따르면 INTERSECT 연산자가 다른 집합 연산자보다 우선 순위를 가지며 MySQL에서는 지원하지 않지만 복합 쿼리를 괄호로 묶어서 처리되는 순서를 지정할 수도 있다
SELECT customer.first_name, customer.last_name
FROM customer
WHERE customer.first_name like 'A%'
UNION
SELECT actor.first_name, actor.last_name
FROM actor
WHERE actor.first_name like "A%"
UNION
SELECT staff.first_name, staff.last_name
FROM staff
WHERE staff.first_name like "B%"
위의 예제에서는 첫 번째, 두 번째 쿼리가 UNION을 통해 결합되고 그 결과가 두 번째 UNION을 마지막 쿼리와 결합된다
SELECT customer.first_name, customer.last_name
FROM customer
WHERE customer.first_name like 'A%'
UNION
(SELECT actor.first_name, actor.last_name
FROM actor
WHERE actor.first_name like "A%"
UNION
SELECT staff.first_name, staff.last_name
FROM staff
WHERE staff.first_name like "B%"
)
하지만 위의 예제에서는 두 번째, 세 번째 쿼리가 UNION을 통해 결합되고 그 결과가 다시 UNION을 통해 첫 번째 쿼리와 결합된다
![[ 살펴보기 ] RDB - Relationships](https://cdn.hashnode.com/res/hashnode/image/upload/v1739711556668/48dc9e84-a621-42aa-9c9f-5fc5c436f0ec.jpeg)
![[ 살펴보기 ] MySQL - Data types](https://cdn.hashnode.com/res/hashnode/image/upload/v1739593589113/530f8704-4d27-42c9-a451-bb5c63150b99.jpeg)
![[ 살펴보기 ] TypeORM - Transactions, Migration](https://cdn.hashnode.com/res/hashnode/image/upload/v1739106042581/980b8133-61d4-406a-a026-65be9c28eace.jpeg)
![[ 살펴보기 ] TypeORM - Relations](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666874402/b688bd0b-b6bb-4f43-87d8-c1b46b59f1b7.jpeg)
![[ 살펴보기 ] TypeORM - Basics](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666803591/bef5df17-7dc7-4123-ae55-004d5042df39.jpeg)