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를 보자: t1t2:

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);

다음의 구문은 t1t2 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을 덧붙인다. 다음의 사진은 UNIONJOIN의 차이를 보여준다.



MySQL UNION과 column alias 예시

증명을 위해 다음의 customersemployees tables를 사용할 것이다:


employeescustomersfirstNamelastName을 하나의 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;

employeescustomers를 구별하기 위해 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을 정렬하는데 좋은 예시는 아니다.