Сообщить об ошибке.

MySQL: 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 берется каждая строка. Дополнительные столбцы также могут содержать другую идентифицирующую информацию, например строку, указывающую имя таблицы.