UNION
UNION
우리는 지금까지 JOIN, 서브쿼리라는 강력한 도구들을 배웠다. 이 기술들의 공통점은 기존 테이블의 정보를 조합하거나 필터링해서, 우리가 원하는 형태의 '하나의 결과 집합(Result Set)' 을 만들어내는 것이었다.
JOIN 은 여러 테이블을 옆으로(수평으로) 붙여서 더 많은 정보를 가진 컬럼들을 만드는 기술이었다면, UNION 은 여러 개의 결과 집합을 아래로(수직으로) 이어 붙여서 더 많은 행을 가진 하나의 집합으로 만드는 기술이다.
이 개념을 이해하기 위해서, 오늘의 문제 상황을 살펴보자.
"우리 쇼핑몰은 현재 활동 중인 고객을 users 테이블에, 과거에 탈퇴한 고객을 retired_users 라는 별도의 테이블에 보관하고 있다. 연말을 맞아 모든 고객(활동+탈퇴)에게 감사 이메일을 보내기 위해, 두 테이블에 흩어져 있는 이름과 이메일을 합쳐서 하나의 전체 목록을 만들어야 한다."
이 업무는 JOIN 으로 해결할 수 없다. 두 테이블은 서로 연결된 관계가 아니라, 구조는 비슷하지만 분리된 변개의 집합이기 때문이다.
UNION 의 개념과 사용법
우리에게는 두 개의 고객 명단이 있다.
1. 활동 고객 명단(users 테이블)
users 테이블) select name, email from users; 2. 탈퇴 고객 명단(retired_users 테이블)
retired_users 테이블) select name, email from retired_users; UNION 연산자는 이 두개의 SELECT 문의 결과를 하나로 합쳐준다. 사용법은 아주 간단하다. 두 SELECT 문 사이에 UNION 키워드를 끼워주면 된다.
select name, email from users
union
select name, email from retired_users; UNION 사용의 핵심 규칙
UNION 을 사용할 때는 반드시 지켜야 할 중요한 규칙이 있다.
UNION으로 연결되는 모든SELECT문은 컬럼의 개수가 동일해야 한다.각
SELECT문의 같은 위치에 있는 컬럼들은 서로 호환 가능한 데이터 타입이어야 한다. (예 : 숫자 타입은 숫자 타입끼리, 문자 타입은 문자 타입끼리)최종 결과의 컬럼 이름은 첫 번째
SELECT문의 컬럼 이름을 따른다.
결과를 살펴보면, 두 테이블(users, retired_users) 간 중복된 데이터가 있다면 최종 결과에서는 단 한번만 나타난다.
이것이 UNION 의 특징이다. UNION 은 기본적으로 두 결과 집합을 합친 뒤, 완전히 중복되는 행은 자동으로 제거하여 고유한 값만 남긴다.
하지만 의도적으로 중복을 허용해야 하거나, 데이터에 중복이 없다는 것을 이미 알아서 굳이 중복 검사를 할 필요가 없는 경우에는 UNION ALL 을 사용하면 된다.
UNION ALL
UNION 은 데이터 중복을 제거해주는 매우 편리한 기능이지만, 항상 우리에게 필요한 기능일까?
"마케팅팀에서 두 종류의 고객에게 이벤트 안내 메일을 보내려고 한다. 첫 번째 그룹은 '전자기기' 카테고리의 상품을 구매한 이력이 있는 고객이고, 두 번째 그룹은 '서울'에 거주하는 고객이다. 두 그룹의 명단을 합쳐서 전체 발송 목록을 만들고 싶다."
여기서 중요한 질문이 생긴다. '서울'에 살명서 '전자기기'를 구매한 고객은 두 그룹에 모두 속하게 되는데, 이 고객을 최종 목록에 한 번만 포함해야 할까? 아니면 중복을 허용해도 될까?
정답은 "비지니스 요구사항에 따라 다르다" 이다. 하지만 이 선택에 따라 우리는 UNION, UNION ALL 중 무엇을 쓸지 결정해야 한다.
UNION, UNION ALL 차이
UNION : 두 결과 집합을 합친 후, 중복된 행을 제거한다.
UNION ALL : 중복 제거 과정 없이 두 결과 집합을 그대로 모두 합친다.
실무 가이드 : 성능이 핵심이다.
"그럼 언제 무엇을 사용해야 하는가?" 라는 질문에 대한 답은 성능에 있다.
결론부터 말하면, UNION ALL 이 UNION 보다 훨씬 빠르다.
왜 그럴까? 데이터베이스의 입장에서 생각해보자.
UNION: 두 결과를 합친 뒤, 중복을 제거하기 위해서 데이터베이스는 보이지 않는 곳에서 추가 작업을 해야 한다. 보통 전체 결과를 정렬(Sort) 후, 서로 인접한 행들을 비교하여 중복을 찾아내는 과정을 거친다. 데이터의 양이 수십만, 수백만 건이라면 이 정렬과 비교 작업은 엄청난 비용과 시간을 소모한다.UNION ALL: 이런 추가 작업이 전혀 없다. 그냥 첫 번째SELECT결과 아래에 두 번째SELECT결과를 가져다 붙이기만 하면 된다.
따라서 실무에서는 다음의 가이드라인을 따르는 것이 좋다.
중복을 제거해야만 하는 명확한 요구사항이 있을 때만
UNION을 사용한다.그 외의 경우에는
UNION ALL을 우선적으로 사용한다.
가장 중요한 실무 팁은 이것이다. "중복을 제거할 필요가 없다고 한다면, 항상 UNION ALL 을 사용하자"
UNION 정렬
UNION, UNION ALL 을 사용하여 여러 SELECT 문의 결과를 합칠 때, 최종 결과 집합에 대해서 정렬을 적용할 수 있다. 이때 ORDER BY 절의 위치가 중요하다.
ORDER BY 절은 전체 UNION 연산의 가장 마지막에 한 번만 사용해야 한다. 만약 각 SEELCT 문 안에 ORDER BY 를 사용하면 에러가 발생하거나, 예상과 다른 결과가 나올 수 있다. 왜냐하면 UNION 은 각 SELECT 문의 개별적인 정렬 순서가 아니라, 합쳐진 최종 결과 전체에 대한 순서를 결정해야 하기 때문이다.
Last updated