본문 바로가기
CS/DataBase

데이터베이스 첫걸음 정리 - 31장. 집합 연산

by yongckim 2022. 10. 1.
728x90
반응형

SQL과 집합

RDBMS, 관계형 데이터베이스는 관계형 모델을 채택한 데이터베이스입니다.

관계형 모델에서 관계형은 수학 집합론의 관계형 이론에서 유래했습니다.

집합론이라고 거창하게 말하지만 결국 데이터베이스의 데이터를 집합으로 간주해 다루기 쉽게 하자는 것이 목표입니다.

데이터베이스에서 테이블이 집합, 테이블의 하나의 행이 집합의 요소에 해당합니다.

행은 여러개의 열로 구성될 수 있으므로, 복수의 값이 요소가 될 수 있습니다.

 

SELECT 명령을 실행하면 데이터베이스에 질의하며 그 결과 몇 개의 행이 반환됩니다. 이때, 반환된 결과 전체를 하나의 집합이라고 생각하시면 됩니다.

합집합

합집합은 집합을 서로 더하는 것을 말합니다.

먼저 A와 B라는 두 개의 집합이 존재한다고 했을 때, A 집합에는 {1, 2, 3}이라는 세 개의 요소가 있고 B 집합에는 {2, 10, 11}이라는 세 개의 요소가 있다고 가정해봅시다.

집합 A와 B의 합집합을 구하면 그 결과는 {1, 2, 3, 10, 11}이 됩니다.

위의 벤 다이어그램으로 설명하면 두 개의 집합을 모두 합한 부분이 합집합의 결과입니다.

이때, 두 개 집합에서 겹쳐지는 부분인 “2”라는 요소는 계산 결과로는 하나밖에 나타나지 않습니다.

UNION을 이용한 합집합

SQL에서는 SELECT 명령의 실행결과를 하나의 집합으로 다룰 수 있습니다.

합집합을 계산하고 싶다면 UNION 키워드를 사용합니다.

UNION 키워드를 사용하기 전에 다음과 같은 테이블이 있다고 가정해봅시다.

SELECT * FROM table_a;

SELECT * FROM table_b;

UNION을 통해 합집합을 하기 위해서는 두 집합(SELECT 명령)을 다음과 같이 연결하여 사용할 수 있습니다.

집합 A UNION 집합 B 

다음은 UNION 사용예시입니다.

SELECT * FROM table_a
UNION
SELECT * FROM table_b;

두 SELECT 명령의 실행결과를 UNION 명령을 통해 합집합으로 묶어 결과가 출력된 것을 확인할 수 있습니다.

UNION을 사용하면 여러개의 SELECT 명령을 하나로 묶을 수 있습니다.

이때, 각각의 SELECT 명령의 열의 내용은 서로 일치해야 합니다.

예를 들어 다음과 같이 열 구성이 완전히 다른 테이블은 UNION으로 묶을 수 없습니다.

SELECT * FROM sample;

SELECT * FROM sample
UNION
SELECT * FROM table_a;

단, 열을 따로 지정하여 각 SELECT 명령에서 집합의 요소가 데이터를 서로 맞춰주면 UNION 명령으로 실행할 수 있는 쿼리가 됩니다.

SELECT p FROM sample 
UNION 
SELECT a FROM table_a;

SELECT 명령들을 UNION으로 묶을 때 나열 순서는 합집합의 결과에 영향을 주지 않습니다.

단, 결과값의 나열 순서가 내부처리에 의해서 달라질 수도 있습니다.

UNION을 사용할 때의 ORDER BY

UNION으로 SELECT 명령을 결합해 합집합을 구하는 경우 각 SELECT 명령에 ORDER BY를 지정해 정렬할 수는 없습니다.

ORDER BY를 지정할때는 마지막 SELECT 명령에만 지정하도록 합니다.

예를 들어 다음과 같은 쿼리를 실행하면 에러가 발생합니다.

SELECT * FROM table_a ORDER BY a
UNION
SELECT * FROM table_b;

ORDER BY로 정렬할 수 없다는 뜻이 아니라 합집합의 결과를 정렬해야 하므로, 가장 마지막의 SELECT 명령에 ORDER BY를 사용해야 합니다.

다음 쿼리처럼 마지막에 ORDER BY를 지정하면 정상적으로 작동됩니다.

SELECT * FROM table_a
UNION
SELECT * FROM table_b ORDER BY a;

단, UNION의 열 이름이 다를 경우 AS 키워드를 통해 열 이름을 맞춰주어야 정상적으로 동작합니다.

 

UNION ALL

UNION은 합집합을 구하는 것이므로 두 개의 집합에서 겹치는 부분은 공통 요소가 됩니다.

예를 들어 앞에서 살펴본 예제에서는 양쪽 모두 2라는 요소가 포함되어 있었습니다.

이때 합집합을 통해 계산하면 2라는 요소는 하나만 존재하게 됩니다.

즉, 두 명령의 실행결과에 DISTINCT를 걸어 중복을 제거한 것과 같은 결과가 나오게 됩니다.

수학에서 말하는 집합은 중복값이 존재하지 않는 것을 전제로 하기 때문에 UNION의 결과도 중복 값이 제거되어 있습니다.

하지만, 경우에 따라 중복을 제거하지 않고 2개의 SELECT 명령의 결과를 그냥 합치고 싶을 수 있습니다.

이런 경우에 UNION ALL을 사용하면 됩니다.

SELECT 명령에서 중복을 제거할 때는 SELECT 구에 DISTINCT를 지정합니다. 이때 기본값은 ALL로, 명시적으로 지정하거나 생략할 수도 있었습니다.

UNION의 경우는 기본 동작이 DISTINCT이고, 모든 결과를 얻고 싶을 때는 ALL을 추가적으로 지정해야 합니다.

단, SELECT ALL을 사용한 것처럼 UNION에 DISTINCT를 붙여 UNION DISTINCT라는 문법은 허용되지 않습니다.

 

SELECT * FROM table_a
UNION ALL
SELECT * FROM table_b;

중복되는 요소인 2가 잘 나오는 것을 확인할 수 있습니다.

UNION에서는 이미 존재하는 값인지 검사하는 처리가 필요한 만큼 UNION ALL이 성능상 유리할 경우가 있습니다.

즉, 중복 값이 없는 경우에는 UNION ALL을 사용하는 편이 좋은 성능을 보여줍니다.

교집합과 차집합

SQL을 이용해 교집합과 차집합도 구할 수 있습니다.

교집합은 INTERSECT를, 차집합은 EXCEPT를 (Oracle의 경우는 MINUS) 사용합니다.

 교집합과 차집합은 MySQL에서는 지원되지않습니다.

 

정리

  • 관계형 데이터베이스는 관계형 모델을 채택한 데이터베이스로 수학 집합론의 관계형 이론에서 유래했습니다. 집합론을 이용해서 데이터베이스의 데이터를 집합으로 간주해 다루기 쉽게 하자는 것이 목표입니다.
  • 데이터베이스에서 테이블이 집합, 테이블의 하나의 행이 집합의 요소에 해당합니다.
  • 합집합은 집합을 서로 더하는 것으로, SQL에서 UNION 명령을 통해 합집합 연산을 할 수 있습니다.
  • UNION으로 합집합의 결과를 정렬하고 싶을 경우 맨 마지막의 SELECT 문에 ORDER BY를 사용해야 합니다. (이때 열 이름이 같아야 하며, 다르다면 별명으로 같게 지정해야 합니다.)
  • UNION으로 합집합을 계산할 때 중복을 허용하고 싶으면 ALL 명령을 붙여 UNION ALL을 사용하면 됩니다.
  • 교집합은 INTERSECT를, 차집합은 EXCEPT를 (Oracle의 경우는 MINUS) 사용합니다. (MySQL에서는 지원되지 않습니다.)
반응형