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을 정렬하는데 좋은 예시는 아니다.