합집합이란 집합 연산에서 집합끼리 서로 더한 것을 의미합니다.
SQL에서는 합집합을 계산하기 위해 UNION 키워드를 사용합니다.
sample71_a
과 sample71_b
가 존재한다고 가정해봅시다.--sample71_a
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |
+------+
--sample71_b
+------+
| b |
+------+
| 2 |
| 10 |
| 11 |
+------+
sample71_a
와 sample71_b
의 합집합을 구하는 방법은 아래와 같습니다.mysql > SELECT * FROM sample71_a UNION SELECT * FROM sample71_b;
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |
| 10 |
| 11 |
+------+
5 rows in set (0.00 sec)
이때 유의할 점은 세미콜론(;)은 명령문의 종료를 의미하기 때문에 꼭 맨 마지막에 붙여야 한다는 것입니다.
mysql > SELECT a FROM sample71_a UNION SELECT b FROM sample71_
ORDER BY
명령을 가장 마지막 SELECT
명령에만 사용할 수 있습니다. 별명(AS)
을 동일하게 지정하여 어떤 열을 정의해야 하는 지 정확하게 ORDER BY
명령으로 넘겨줘야 합니다.mysql > SELECT a AS age FROM sample71_a
UNION
SELECT b AS age FROM sample71_b
ORDER BY age DESC;
+------+
| age |
+------+
| 11 |
| 10 |
| 3 |
| 2 |
| 1 |
+------+
5 rows in set (0.00 sec)
UNION 키워드는 기본적으로 수학의 합집합과 동일하기 때문에 중복된 요소를 제거하여 결괏값을 반환합니다.
그러나 만약 중복된 요소도 결괏값으로 얻고 싶다면 UNION ALL
키워드를 사용하면 됩니다.
이는 중복을 제거하는 DISTINCT
키워드와 반대입니다.
기본적으로 ALL
키워드가 생략되어 있기 때문에 SELECT
명령을 사용할 때 DISTINCT
키워드를 추가하지만 중복된 값을 반환합니다.
반대로 UNION
의 경우 DISTINCT
키워드가 기본이라고 생각하면 편합니다.
그러나 실제로 DISTINCT
명령이 생략되어 있는 것은 아니기 때문에 UNION DISTINCT
와 같은 명령은 오류
를 반환하니 유의해야 합니다.
테이블 sample71_a와 sample71_b의 중복된 요소를 포함한 합집합 결과를 확인하는 방법은 아래와 같습니다.
그러면 앞서 중복되어 제거되었던 값 2가 이번에는 중복되어 결괏값으로 반횐된 것을 확인할 수 있습니다.
mysql > SELECT a AS age FROM sample71_a
UNION ALL
SELECT b AS age FROM sample71_b ORDER BY age DESC;
+------+
| age |
+------+
| 11 |
| 10 |
| 3 |
| 2 |
| 2 |
| 1 |
+------+
6 rows in set (0.00 sec)
교집합이란 두 개의 집합이 겹치는 부분, 다시 말해 공통 부분을 의미하며 차집합이란 하나의 집합을 기준으로 다른 쪽의 집합을 제거하고 남은 부분, 다시 말해 기준이 되는 집합에서 다른 집합과 공통된 부분을 제거하고 남은 순수 부분을 의미합니다.
차집합의 결과가 아무런 요소도 존재하지 않는 공집합인 경우 이는 곧 두 개의 집합이 완전히 같다는 걸 의미합니다.
교집합을 구하기 위해서는 INTERSECT
키워드를 사용하며 차집합을 구하기 위해서는 EXCEPT
키워드를, Oracle에서는 MINUS
키워드를 사용합니다.
MySQL에는 별도의 키워드가 존재하지 않기 때문에 직접 이를 계산하여 구해야 합니다.
MySQL에서 교집합과 차집합을 아래와 같이 EXISTS
및 NOT EXISTS
키워드를 통한 상관 서브쿼리를 활용하여 구현할 수 있습니다.
--sample71_a
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |
+------+
--sample71_b
+------+
| b |
+------+
| 2 |
| 10 |
| 11 |
+------+
// a에서 b의 교집합
mysql> SELECT * FROM sample71_a
WHERE EXISTS ( SELECT * FROM sample71_b
WHERE sample71_b.b = sample71_a.a );
+------+
| a |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
// a에서 b의 차집합
mysql> SELECT * FROM sample71_a
WHERE NOT EXISTS ( SELECT *
FROM sample71_b WHERE sample71_a.a = sample71_b.b );
+------+
| a |
+------+
| 1 |
| 3 |
+------+
2 rows in set (0.00 sec)