본문 바로가기
프로그래밍

[SQL] 합집합, 교집합, 차집합, 대칭차집합 구현하기

by youngbamer 2021. 9. 28.
반응형

 

집합 개념을 사용한다면 SQL 문을 작성할 때 굉장히 효율적으로 작성할 수 있다.

데이터를 문자로 보는게 아니라 집합이라는 전체적인 이미지로 생각한다음 코드로 구현하기 때문이다.

 

오늘은 합집합, 교집합, 차집합, 대칭차집합을 SQL 문으로 구현하는 방법에 대해 포스팅하겠다.

컬럼의 개수와 데이터 타입이 같은 tableA, tableB와 Primary key 값 str을 가지고 예를 들어보자.

 

합집합

SELECT str FROM tableA UNION SELECT str FROM tableB;

 

UNION은 두개의 SELECT 결과를 합칠 수 있다.

합친 결과에서 중복되는 행은 하나만 표시한다.

컬럼의 개수가 같고 각 컬럼의 데이터 타입이 같을 때 사용할 수 있다.

 

 

교집합

SELECT a.str FROM tableA a, tableB b WHERE a.str = b.str;

 

FROM에서 두개의 테이블을 호출하면서 WHERE로 서로 key 값을 같게하여 호출한다.

같은 데이터만 호출하므로 교집합을 반환한다.

 

 

차집합

차집합은 조인으로도쉽게 구현할 수 있다.

 

SELECT a.str FROM tableA a LEFT JOIN tableB b ON a.str = b.str WHERE b.str IS NULL;

 

tableA를 기준으로 tableB와 키값을 같게 하여 LEFT JOIN 했다.

그 결과 tableA의 키값은 항상 존재할 수 있으나 b의 키값은 NULL이 생길 수 있다.

왜냐하면 tableA를 기준으로 하여 LEFT JOIN 하였기 때문이다.

그래서 마지막 b의 키값이 NULL인 부분을 반환하면 완벽히 tableB의 요소가 제외된 차집합을 가져올 수 있다.

 

SELECT str FROM tableA WHERE str NOT IN ( SELECT DISTINCT str FROM tableB );

 

조인 없이도 구현할 수 있다.

tableB에서 중복되지 않은 유니크한 키값들을 tableA의 키값에서 제외하여 반환하는 구문이다.

 

대칭차집합

SELECT str FROM ( SELECT str FROM tableA UNION ALL SELECT str FROM tableB ) AS tmp
GROUP BY str HAVING COUNT(*)=1

 

SELECT를 이용해서 직관적으로 잘 구현한 것 같다.

일단 tableA의 모든 키값과 tableB의 모든 키값을 합친 다음에,

다시 한번 키의 중복된 부분들을 그룹으로 묶어주는 GROUP BY를 사용하고

마지막으로 그 조건으로 GROUP된 행의 숫자가 1일때를 반환한다.

 

즉, 각 테이블의 키값이 중복되지 않은(교집합이 없는)

데이터를 반환할 수 있으므로 대칭차집합 값을 구할 수 있다.

 

SELECT str FROM tableA WHERE str NOT IN ( SELECT DISTINCT str FROM tableB )
UNION ALL SELECT str FROM
tableB WHERE str NOT IN ( SELECT DISTINCT str FROM tableA )

 

이 구문도 매우 직관적이다.

각 테이블에서 상대 테이블의 중복되지 않은 키값을 포함되지 않게 한 뒤 합친다는 구문이다.

 

SQL문을 작성할 때 보통 이미지로 계획을 짜는게 직관적이고 인간이 이해하기도 쉽다.

따라서 집합으로 표현할 경우 손쉽게 SQL 구문을 짤 수 있다.

반응형