Skip to main content

Command Palette

Search for a command to run...

[ 살펴보기 ] Sql - 집합 연산

Updated
3 min readView as Markdown
[ 살펴보기 ] Sql - 집합 연산
C

A developer living in Busan, Korea

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을 통해 첫 번째 쿼리와 결합된다

More from this blog

[ 살펴보기 ] TypeORM - Transactions, Migration

Transation Database 종류에 따라 detail한 부분은 차이점이 조금씩 있겠지만 각 sql statement는 개별적인 transaction block을 통해 실행되며 Database 설정에 따라 sql statement의 실행 결과가 자동으로 commit되어 영구히 적용되거나 commit을 직접 실행하기 전까지는 영구히 적용되지 않을 수 있다. 대부분의 경우 default로 sql statement 실행 결과가 자동으로 comm...

Feb 9, 20256 min read
[ 살펴보기 ] TypeORM - Transactions, Migration

Dev Diary

184 posts