[SQL] 레코드 집합 합치기 - UNION

2024. 9. 11. 17:22Language/SQL

 이전 학습한 'JOIN' 이 특정 컬럼을 기준으로 두 테이블의 레코드를 합치는 기능을 한다면, 'UNION' 은 같은 컬럼구성을 갖는 두 집합의 레코드를 합쳐 하나의 집합으로 만드는 기능을 한다. 

 

1. 기본 문법

SELECT column1, column2
FROM table1

UNION (or UNION ALL)

SELECT column1, column2
FROM table2

 

명확한 'UNION' 의 기능은 '두 개이상의 SELECT 문의 결과 집합을 결합' 하는 것이라 한다. 당연하게도 결합할 집합은 같은 개수의 컬럼을 가져야하고 컬럼구성(컬럼명, 컬럼타입)이 같아야 한다. 위의 문법을 통해 좀 더 설명하면 아래의 조건을 만족해야 하는 것이다.

  • 'table1.column1' 과 'table2.column1' 의 이름과 타입이 같아야 한다. 나머지 컬럼들도 해당 조건을 만족해야 한다.
  • 컬럼들이 그룹을 이루어 위의 조건을 만족해야 하기에, 합칠 SELECT 문의 결과 집합들은 모두 같은 컬럼(속성) 개수를 가져야 한다.

'JOIN' 이 '가로' 로 확장되는 느낌이라면 'UNION' 은 '세로' 로 확장되는 느낌이다. 'UNION' 과 'UNION ALL' 의 기능은 좀 다른데 'UNION' 은 모든 컬럼 값이 중복인 레코드를 제외하는 반면 'UNION ALL' 은 중복 제거 없이 모든 레코드를 포함한 집합을 생성한다.

 

 

2. 사용 예시

 예시를 만들기 어렵다 판단 'UNION' 을 활용해 해결한 코드 문제를 가져왔다. 정확한 문제에 대한 내용은 여기서 확인 할 수 있다.

SELECT DATE_FORMAT(sales_date, '%Y-%m-%d') sales_date, product_id, user_id, sales_amount
FROM online_sale
WHERE sales_date LIKE '2022-03%'

UNION ALL

SELECT DATE_FORMAT(sales_date, '%Y-%m-%d') sales_date, product_id, NULL, sales_amount
FROM offline_sale
WHERE sales_date LIKE '2022-03%'
ORDER BY sales_date, product_id, user_id

 

 예시를 만들기 어렵다고 판단한 이유는 사실 '실무에서는 'UNION' 을 사용하지 않게끔 DB 가 모델링 되어야 하지 않나?' 라는 생각을 가지고 있기 때문이다. 코드 문제도 '문제' 이기 때문에 해결을 위해 'UNION' 을 사용했을 뿐이지 사실 한 테이블에 모든 구매 정보(데이터)를 가지게하고 구입이 '온라인' 인지 '오프라인' 인지 구분할 수 있는 컬럼을 추가하는 것이 실상 데이터 처리를 하는데 더 편리하고 성능을 유지할 수 있지 않을까?

 

물론 아직 경험이 부족하기에 예시가 안 떠오른 것일 수 있지만 어떻게든 예시를 만들기에는 가지고 있는 샘플 데이터가 예시를 만들수 없을 것 같아 이런 방식을 택하게 되었다.

 

 

3. 마무리

 해당 내용을 실무자에게 이야기하고 실무 경험의 예를 들어보았는데 '개발' 외적으로 부득이하게 테이블을 나누는 경우가 있다고 한다. 듣기로는 '개인정보' 관련 법 때문에 휴면 회원의 데이터는 현재 활동하는 회원의 데이터와 분리해야 하는데 어떠한 요구로 휴먼 회원의 데이터와 현재 활동 중인 회원의 데이터를 함께 사용해 결과를 도출하는 경우 'UNION' 을 사용했던 경험이 있다 하였다.

 

결과적으로는 '개발' 에서는 생각한 부분이 맞았지만 실무에서는 외적인 요소(상황)때문에 다르게 구현될 수 있다는 걸 알게 되었다. 정말 '개인정보법' 은 생각도 못하였는데 많은 도움이 되었다. 일단은 'UNION' 이라는 함수가 있고 해당 함수를 통해 어떤 결과를 도출할 수 있는지를 알았다는 거에 만족해야 할 것 같다.


참고 문서