MySQL - 집합연산 (UNION)

Posted by Juri on November 9, 2021

RDBMS 은 수학 집합론의 관계형 이론에서 유래했다. 데이터베이스의 데이터를 집합으로 간주해 다루기 쉽게 하자는 것이다.

벤 다이어그램과 테이블을 대응해 생각하면 쉽다. 벤 다이어그램의 원 안에 있는 요소가 테이블의 행에 해당한다. SELECT 명령이 반환하는 여러개의 행을 하나의 집합이라고 생각하면 된다.

UNION - 합집합

수학에서 사용하는 합집합의 기호 ∪ 대신 SQL은 UNION을 사용한다.

A ∪ B = A UNION B

예제

a
1
2
3
b
3
4
5
1
2
3
SELECT * FROM test_a
UNION
SELECT * FROM test_b;

결과

a
1
2
3
4
5

이 때, 합치는 열의 내용이 서로 일치해야 한다. 위의 예시는 열의 이름은 다르지만 열 개수와 자료형이 서로 같아 일치한다고 할 수 있다. SELECT 명령들을 UNION으로 묶을 때 나열순서는 결과에 영향을 주지 않는다. 단, 결과값의 나열 순서는 다를 수 있다. 마지막 SELECT 명령에 ORDER BY를 지정해 결과값을 정렬할 수 있다.
열의 이름이 일치하지 않을 경우엔 동일한 별명을 붙여 ORDER BY를 지정할 수 있다.

1
2
3
SELECT a AS c FROM test_a
UNION
SELECT b AS c FROM test_b ORDER BY -c;

결과

c
5
4
3
2
1

수학에서 집합은 중복값이 존재하지 않는 것을 전제로 하듯 UNION을 한 결과에도 중복값이 제거되어 있다. 중복을 제거하고 싶지 않을 때는 UNION ALL을 사용한다.

1
2
3
SELECT * FROM test_a
UNION ALL
SELECT * FROM test_b;
a
1
2
3
3
4
5

UNION에서는 중복값의 여부를 검사하는 처리가 필요한 만큼, UNION ALL이 성능적으로 더 유리할 경우가 있다. 중복값이 없는 경우엔 UNION ALL을 사용하는 편이 성능에 유리하다.

참고로 MySQL에서는 차집합, 교집합 연산을 지원하지않는다.

FULL OUTER JOIN

A집합과 B집합이 있다고 했을 때, A집합과 B집합의 합집합을 FULL OUTER JOIN으로 표현할 수 있다. 하지만, MySQL에서는 지원되지 않으므로 합집합을 표현할 때 UNION을 사용한다.

1
2
3
4
5
6
7
SELECT *
FROM A
	 LEFT JOIN B ON A.ID = B.A_ID
UNION
SELECT *
FROM A
	 RIGHT JOIN B ON A.ID = B.A_ID

JOIN은 옆으로 테이블이 확장되고 (컬럼 추가) UNION은 아래로 테이블이 확장된다 (로우 추가).