2021-12-13 16:42 작성
My SQL basic 메모
Table of contents
UNION 연산자
MySQL UNION 연산자는 복수의 쿼리에서 반환된 두 개 이상의 result sets를 통합한다. 다음은 UNION 연산자의 기본 문법이다:
SELECT column_list
UNION [DISTINCT | ALL]
SELECT column_list
UNION [DISTINCT | ALL]
SELECT column_list
...
UNION 연산자를 사용해 복수의 쿼리에서 반환된 result set을 통합하기 위해 다음의 기본적인 규칙을 지켜야만 한다:
- 첫째, 모든
SELECT구문들에서 나타나는 columns의 수와 순서는 같아야 한다. - 둘째, columns의 데이터 타입은 같거나 호환 가능해야 한다.
기본적으로 UNION 연산자는 DISTINCT 연산자를 명시하지 않아도 반복되는 rows를 제거한다.
다음의 샘플 tables를 보자: t1과 t2:
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 (
id INT PRIMARY KEY
);
CREATE TABLE t2 (
id INT PRIMARY KEY
);
INSERT INTO t1 VALUES (1), (2), (3);
INSERT INTO t2 VALUES (2), (3), (4);
다음의 구문은 t1과 t2 tables에서 반환되는 result sets를 통합한다.
SELECT id
FROM t1
UNION
SELECT id
FROM t2;
output: 최종 result set은 쿼리들에서 반환되는 개별 result set의 distinct values로 구성된다.
| id |
|---|
| 1 |
| 2 |
| 3 |
| 4 |
2와 3을 가진 rows은 중복인자이기 때문에 UNION은 고유 value만 유지하고 나머지는 제거한다.
다음의 벤 다이어그램은 두 result sets의 union을 명확히 보여준다.
만약 UNION ALL을 명시적으로 사용하면, 반복 rows는 가능한 한 reuslt에 남게 된다. UNION ALL은 반복인자를 처리할 필요가 없기 때문에 UNION DISTINCT보다 더 빠른 퍼포먼스를 보인다.
SELECT id
FROM t1
UNION ALL
SELECT id
FROM t2;
output:
| id |
|---|
| 1 |
| 2 |
| 3 |
| 2 |
| 3 |
| 4 |
UNION vs. JOIN
JOIN은 수평하게 result sets를 통합한다. UNION은 수직으로 result set을 덧붙인다. 다음의 사진은 UNION과 JOIN의 차이를 보여준다.
MySQL UNION과 column alias 예시
증명을 위해 다음의 customers와 employees tables를 사용할 것이다:
employees와 customers의 firstName과 lastName을 하나의 result set으로 통합하고 싶다고 가정해보자, UNION 연산자를 다음과 같이 사용할 수 있다:
SELECT
firstName,
lastName
FROM
employees
UNION
SELECT
contactFirstName,
contactLastName
FROM
customers
ORDER BY firstName, lastName;
output:
| firstName | lastName |
|---|---|
| Adrian | Huxley |
| Akiko | Shimamura |
| Allen | Nelson |
| Andy | Fixter |
| Ann | Brown |
| Anna | O’Hara |
| Annette | Roulet |
| Anthony | Bow |
| Arnold | Cruz |
| Barry | Jones |
| Ben | Calaghan |
| Brian | Chandler |
| Carine | Schmitt |
| Catherine | Dewey |
…
결과물을 보면 알 수 있듯 MySQL UNION은 첫 번째 SELECT 구문의 column 명칭을 결과 column headings(제목)으로 사용하는 것을 할 수 있다.
만약 다른 column headings를 사용하려면 첫 번째 SELECT 구문에서 명시적으로 column aliases를 사용하면 된다:
SELECT
CONCAT(firstName, ' ', lastName) fullname
FROM
employees
UNION
SELECT
CONCAT(contactFirstName, ' ', contactLastName)
FROM
customers;
output:
| fullname |
|---|
| Diane Murphy |
| Mary Patterson |
| Jeff Firrelli |
| William Patterson |
| Gerard Bondur |
| Anthony Bow |
| Leslie Jennings |
| Leslie Thompson |
| Julie Firrelli |
| Steve Patterson |
UNION과 ORDER BY
만약 한 union의 result set을 정렬하고 싶다면 마지막 SELECT 구문에서 ORDER BY를 사용한다.
SELECT
concat(firstName,' ',lastName) fullname
FROM
employees
UNION SELECT
concat(contactFirstName,' ',contactLastName)
FROM
customers
ORDER BY fullname;
employees와 customers를 구별하기 위해 column을 추가할 수 있다:
SELECT
CONCAT(firstName, ' ', lastName) fullname,
'Employee' as contactType
FROM
employees
UNION SELECT
CONCAT(contactFirstName, ' ', contactLastName),
'Customer' as contactType
FROM
customers
ORDER BY
fullname;
output:
| fullname | contactType | +———————–+————-+ | Adrian Huxley | Customer | | Akiko Shimamura | Customer | | Allen Nelson | Customer | | Andy Fixter | Employee | | Ann Brown | Customer | | Anna O’Hara | Customer |
MySQL은 ORDER BY 절을 사용해 column position에 기반한 result set을 정렬하는 대체 option을 제공한다.
SELECT
CONCAT(firstName,' ',lastName) fullname
FROM
employees
UNION SELECT
CONCAT(contactFirstName,' ',contactLastName)
FROM
customers
ORDER BY 1;
그러나 column position으로 result set을 정렬하는데 좋은 예시는 아니다.