13.2.9.3 Оператор UNION
SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]
UNION объединяет результаты нескольких операторов SELECT в один результирующий набор. Пример:
mysql> SELECT 1, 2;
+---+---+
| 1 | 2 |
+---+---+
| 1 | 2 |
+---+---+
mysql> SELECT 'a', 'b';
+---+---+
| a | b |
+---+---+
| a | b |
+---+---+
mysql> SELECT 1, 2 UNION SELECT 'a', 'b';
+---+---+
| 1 | 2 |
+---+---+
| 1 | 2 |
| a | b |
+---+---+
Имена столбцов и типы данных результирующего набора
Имена столбцов результирующего набора UNION берутся из имен столбцов первого оператора SELECT.
Выбранные столбцы, указанные в соответствующих позициях каждого оператора SELECT, должны иметь одинаковый тип данных. Например, первый столбец, выбранный в первом операторе, должен иметь тот же тип, что и первый столбец в других операторах. Если типы данных соответствующих столбцов операторов SELECT не совпадают, типы и длины столбцов в результирующем наборе UNION учитывают значения, полученные всеми операторами SELECT. Например, рассмотрим следующий случай, где длина столбца не ограничена длиной значения из первого оператора SELECT:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',20);
+----------------------+
| REPEAT('a',1) |
+----------------------+
| a |
| bbbbbbbbbbbbbbbbbbbb |
+----------------------+
UNION DISTINCT и UNION ALL
По умолчанию из результирующего набора UNION удаляются дублирующиеся строки. Опциональное ключевое слово DISTINCT имеет тот же эффект, но делает его явным. С опциональным ключевым словом ALL удаление дубликатов не происходит, и результат включает все совпадающие строки из всех операторов SELECT.
Вы можете смешивать операторы UNION
ALL и UNION
DISTINCT в одном запросе. Смешанные типы операторов UNION обрабатываются таким образом, что оператор DISTINCT UNION перекрывает любой оператор ALL UNION слева от него. Явный оператор DISTINCT UNION можно получить, явно используя UNION
DISTINCT, или неявно, используя UNION без последующих ключевых слов DISTINCT или ALL.
ORDER BY и LIMIT в операторах UNION
Чтобы применить клаузу ORDER BY или LIMIT к отдельному оператору SELECT, нужно заключить оператор SELECT в скобки и поместить клаузу внутрь скобок:
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
Предыдущие версии MySQL могли допускать такие операторы без скобок. В MySQL 5.7 требование к скобкам обязательно.
Использование ORDER BY для отдельных операторов SELECT ничего не говорит о порядке появления строк в конечном результате, потому что оператор UNION по умолчанию создаёт неупорядоченный набор строк. Следовательно, ORDER BY в этом контексте обычно используется в сочетании с LIMIT, чтобы определить подмножество выбранных строк для извлечения для оператора SELECT, хотя это не обязательно влияет на порядок этих строк в конечном результирующем наборе UNION. Если ORDER
BY появляется без LIMIT в операторе SELECT, он оптимизируется, потому что не имеет эффекта.
Чтобы использовать клаузу ORDER BY или LIMIT для сортировки или ограничения всего результирующего набора UNION, заключите отдельные операторы SELECT в скобки и поместите клаузу ORDER BY или LIMIT после последнего оператора:
(SELECT a FROM t1 WHERE a=10 AND B=1)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2)
ORDER BY a LIMIT 10;
Оператор без скобок эквивалентен оператору в скобках, как показано выше.
Такой оператор ORDER BY не может использовать ссылки на столбцы, включающие имя таблицы (то есть имена в формате tbl_name.col_name). Вместо этого укажите псевдоним столбца в первом операторе SELECT и ссылайтесь на псевдоним в клаузе ORDER BY. (В качестве альтернативы вы можете сослаться на столбец в операторе ORDER BY по его позиции. Однако использование позиций столбцов устарело.)
Кроме того, если столбец, по которому производится сортировка, имеет псевдоним, клаузу ORDER
BY необходимо ссылаться на псевдоним, а не на имя столбца. Первый из следующих операторов допустим, но второй приводит к ошибке Unknown column 'a' in 'order clause':
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b;
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;
Чтобы строки в результирующем наборе UNION состояли из наборов строк, извлечённых каждым оператором SELECT один за другим, выберите дополнительный столбец в каждом операторе SELECT для использования в качестве столбца сортировки и добавьте клаузу ORDER BY, которая сортирует по этому столбцу после последнего оператора SELECT:
(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col;
Чтобы дополнительно сохранить порядок сортировки внутри отдельных результатов операторов SELECT, добавьте дополнительный столбец в клаузу ORDER BY:
(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col, col1a;
Использование дополнительного столбца также позволяет определить, из какого оператора SELECT происходит каждая строка. Дополнительные столбцы могут также содержать другую идентифицирующую информацию, например, строку, указывающую имя таблицы.
Запросы UNION с агрегатной функцией в клаузе ORDER BY отклоняются с ошибкой. Пример:
SELECT 1 AS foo UNION SELECT 2 ORDER BY MAX(1);
Ограничения оператора UNION
В операторе UNION операторы SELECT являются обычными операторами select, но с следующими ограничениями:
© 2025 Oracle
Licensed under the GPLv2 License.