UNION. Объединение записей из разных таблиц в MySQL

 Оператор UNION

Оператор UNION используется для объединения данных из двух и более таблиц, выводимых с помощью команды SELECT.

Принцип работы оператора UNION в MySQL
Принцип работы оператора UNION в MySQL

Для успешного объединения необходимо выполнить несколько условий:

  • Количество колонок должно быть одинаково для всех объединяемых таблиц.
  • Колонки должны иметь схожие (одинаковые) типы данных.
  • Все колонки должны идти в одном и том же порядке.

Синтаксис оператора UNION

mysql> SELECT column1, column2, ... , columnN FROM table_name1
    -> UNION
    -> SELECT column1, column2, ... , columnN FROM table_name2

По умолчанию UNION выводит только уникальные записи, поэтому если в таблицах встретятся одинаковые записи, то в объединении будет только одна запись.

Если вам важно вывести повторяющие записи, используйте оператор UNION ALL.

mysql> SELECT column1, column2, ... , columnN FROM table_name1
    -> UNION ALL
    -> SELECT column1, column2, ... , columnN FROM table_name2

Пример использования оператора UNION

В качестве примера возьмем две таблицы carriers (компании, оказывающие услуги доставки) и suppliers (поставщики) из базы данных для книжного интернет магазина Bookstore.

Выведем имя компании (name) и дату окончания действия договора сотрудничества (contract_expiration_date) из обеих таблиц.

mysql> SELECT id, name, contract_expiration_date FROM suppliers;
+----+----------------------+--------------------------+
| id | name                 | contract_expiration_date |
+----+----------------------+--------------------------+
|  1 | ООО "Книжный мир"    | 2021-02-23               |
|  2 | ООО "Все книги"      | 2025-01-01               |
|  3 | ООО "Книжный склад"  | 2027-06-19               |
+----+----------------------+--------------------------+
3 rows in set (0.00 sec)

mysql> SELECT id, name, contract_expiration_date FROM carriers;
+----+---------------------------+--------------------------+
| id | name                      | contract_expiration_date |
+----+---------------------------+--------------------------+
|  1 | ООО "Скорость"            | 2020-12-31               |
|  2 | ООО "Грузовые перевозки"  | 2021-05-05               |
+----+---------------------------+--------------------------+
2 rows in set (0.00 sec)

Как можем заметить все колонки в обеих таблицах имеют одни и те же имена и тип данных (VARCHAR и DATE).

Допустим нам необходимо кому-либо предоставить список всех компаний с которыми сотрудничает интернет-магазин. В этом случае мы можем объединить данные обеих таблиц следующим образом.

mysql> SELECT name, contract_expiration_date FROM suppliers
    -> UNION
    -> SELECT name, contract_expiration_date FROM carriers;
+---------------------------+--------------------------+
| name                      | contract_expiration_date |
+---------------------------+--------------------------+
| ООО "Книжный мир"         | 2021-02-23               |
| ООО "Все книги"           | 2025-01-01               |
| ООО "Книжный склад"       | 2027-06-19               |
| ООО "Скорость"            | 2020-12-31               |
| ООО "Грузовые перевозки"  | 2021-05-05               |
+---------------------------+--------------------------+
5 rows in set (0.00 sec)

Пример использования UNION и условного оператора WHERE

UNION также можно использовать со всеми дополнительными операторами для команды SELECT.

Например, выведем все компании из двух предыдущих таблиц, в которых дата окончания договора на сотрудничество приходится на 2021 год. Также для более эстетичного вида создадим колонку с номером строки и алиасы для колонок.

mysql> SELECT @n := @n + 1 '№', name AS 'Имя компании',
    -> contract_expiration_date AS 'Дата окончания договора'
    -> FROM carriers, (SELECT @n := 0) m
    -> WHERE contract_expiration_date LIKE '2021%'
    -> UNION
    -> SELECT @n := @n + 1 '№', name AS 'Имя компании',
    -> contract_expiration_date AS 'Дата окончания договора'
    -> FROM suppliers, (SELECT @n := 0) m
    -> WHERE contract_expiration_date LIKE '2021%';
+---+---------------------------+--------------------------+
| № | Имя компании              | Дата окончания договора  |
+---+---------------------------+--------------------------+
| 1 | ООО "Грузовые перевозки"  | 2021-05-05               |
| 2 | ООО "Книжный мир"         | 2021-02-23               |
+---+---------------------------+--------------------------+
2 rows in set (0.00 sec)