UNION
;DISTINCT
и ALL
в инструкции UNION
;ORDER BY
и LIMIT
в инструкции UNION
;MySQL инструкция UNION
позволяет объединить результат нескольких операторов SELECT
в один результирующий набор.
UNION
.SELECT ... UNION [ALL | DISTINCT] SELECT ... UNION [ALL | DISTINCT] SELECT ... ...
Простой пример:
mysql> SELECT 1 AS col1, 2 AS col2 UNION SELECT 'a', 'b'; +------+------+ | col1 | col2 | +------+------+ | 1 | 2 | | a | b | +------+------+
Ограничение: Запросы
UNION
с агрегатной функцией в предложенииORDER BY
отклоняются с ошибкой.SELECT 1 AS foo UNION SELECT 2 ORDER BY MAX(foo); -- Expression #1 of ORDER BY contains -- aggregate function and applies to a UNION
Имена столбцов для результирующего набора UNION
берутся из имен столбцов первого оператора SELECT
.
Выбранные столбцы, перечисленные в соответствующих позициях каждого оператора SELECT
, должны иметь один и тот же тип данных. Например, первый столбец, выбранный первым оператором, должен иметь тот же тип, что и первый столбец, выбранный другими операторами. Если типы данных соответствующих столбцов SELECT
не совпадают, то типы и длины столбцов в результате UNION
учитывают значения, извлеченные всеми операторами SELECT
. Например, рассмотрим следующее, где длина столбца не ограничена длиной значения из первого SELECT
:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',20); +----------------------+ | REPEAT('a',1) | +----------------------+ | a | | bbbbbbbbbbbbbbbbbbbb | +----------------------+
DISTINCT
и ALL
в инструкции UNION
.Повторяющиеся строки из результатов UNION
удаляются по умолчанию. Необязательное ключевое слово DISTINCT
имеет тот же эффект, но делает его явным. При использовании необязательного ключевого слова ALL
удаление повторяющихся строк не происходит, и результат включает все совпадающие строки из всех операторов SELECT
.
Можно смешивать UNION ALL
и UNION DISTINCT
в одном запросе. Смешанные типы UNION
обрабатываются таким образом, что объединение DISTINCT
переопределяет любое объединение ALL
слева от него. Объединение DISTINCT
можно создать явно, используя UNION DISTINCT
, или неявно, используя UNION
без следующего ключевого слова DISTINCT
или ALL
.
ORDER BY
и LIMIT
в инструкции UNION
.Чтобы применить предложение ORDER BY
или LIMIT
к отдельному SELECT
, необходимо заключить инструкцию SELECT
с предложением ORDER BY
или LIMIT
в скобки:
(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);
[Использование ORDER BY
для отдельных операторов SELECT
ничего не значат для порядка, в котором строки будут появляться в конечном результате, т.к. UNION
по умолчанию создает неупорядоченный набор строк. Таким образом, ORDER BY
в этом контексте обычно используется в сочетании с LIMIT
, чтобы определить подмножество выбранных строк для извлечения SELECT
, даже если это не обязательно влияет на порядок этих строк в конечном результате. Если ORDER BY
появляется в SELECT
без LIMIT
, то он оптимизируется, потому что в любом случае это не имеет никакого эффекта.
Чтобы использовать предложение 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
должно ссылаться на псевдоним, а не на имя столбца. Первое из следующих утверждений разрешено, но второе завершается ошибкой: "Unknown column 'a' in ...".
(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
берется каждая строка. Дополнительные столбцы также могут содержать другую идентифицирующую информацию, например строку, указывающую имя таблицы.