UNION: примеры (SQL)

Функция UNION в Microsoft SQL Server
Раздел: Операторы множеств, Множества
UNION(query1 UNION [ALL] query2): Depends on queries

Основные сведения о UNION

Оператор UNION в MS SQL Server предназначен для объединения результирующих наборов данных из двух и более SELECT-запросов в один общий набор. Основная задача оператора — вертикальное соединение строк.

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

По умолчанию оператор выполняет удаление дублирующихся строк из финального результата. Это поведение соответствует использованию необязательного ключевого слова DISTINCT. Альтернативный вариант — UNION ALL — объединяет результаты без проверки на дубликаты, что повышает производительность.

Основные требования к объединяемым запросам:

  • Количество столбцов в каждом SELECT должно быть одинаковым.
  • Соответствующие столбцы должны иметь совместимые типы данных.
  • Имена столбцов в итоговом наборе берутся из первого запроса.

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

Базовые примеры использования

Объединение данных из двух таблиц с удалением дублей:

SELECT 'Сотрудник' AS Тип, Имя, Фамилия FROM Сотрудники
UNION
SELECT 'Клиент', Имя, Фамилия FROM Клиенты
ORDER BY Фамилия;
Тип        | Имя   | Фамилия
-----------|-------|---------
Сотрудник  | Иван  | Петров
Клиент     | Анна  | Сидорова
Сотрудник  | Петр  | Иванов
Клиент     | Ольга | Петрова

Использование UNION ALL для сохранения всех строк, включая повторяющиеся:

SELECT Город FROM Филиалы WHERE Регион = 'Центр'
UNION ALL
SELECT Город FROM Клиенты WHERE Регион = 'Центр';
Город
---------
Москва
Воронеж
Москва
Тула
Москва

Объединение данных с агрегацией:

SELECT Год, SUM(Продажи) AS Сумма FROM Продажи_2023 GROUP BY Год
UNION
SELECT Год, SUM(Продажи) FROM Продажи_2024 GROUP BY Год;
Год | Сумма
----|------
2023| 150000
2024| 180000

Схожие операторы MS SQL

UNION ALL — базовая альтернатива UNION. Не выполняет проверку на дубликаты, что делает его быстрее. Рекомендуется к использованию, когда уникальность строк гарантирована или не требуется.

EXCEPT — возвращает строки из первого запроса, которые отсутствуют в результате второго. Удаляет дубликаты. Полезен для поиска различий между наборами данных.

SELECT ID FROM Таблица1
EXCEPT
SELECT ID FROM Таблица2;

INTERSECT — возвращает только общие строки для всех объединенных запросов. Также удаляет дубликаты. Применяется для поиска пересечений.

SELECT Продукт FROM Заказы_Январь
INTERSECT
SELECT Продукт FROM Заказы_Февраль;

Выбор между операторами зависит от задачи: UNION для объединения, EXCEPT для вычитания, INTERSECT для поиска совпадений.

Аналоги в других СУБД

MySQL / PostgreSQL: Поддерживают стандартные UNION, UNION ALL, EXCEPT (в MySQL — только через LEFT JOIN), INTERSECT. Синтаксис идентичен SQL Server.

-- PostgreSQL пример
SELECT a FROM t1
UNION
SELECT b FROM t2;

Oracle: Операторы UNION, UNION ALL, MINUS (аналог EXCEPT), INTERSECT. Особенность — необходимость совместимости типов данных, включая VARCHAR2 и CHAR.

-- Oracle пример
SELECT имя FROM сотрудники
UNION ALL
SELECT название FROM отделы;

SQLite: Полная поддержка UNION, UNION ALL. INTERSECT и EXCEPT появились с версии 3.22.0. Ограничения по сложности запросов меньше, чем в других СУБД.

-- SQLite пример
SELECT * FROM из_таблицы1
UNION
SELECT * FROM из_таблицы2;

Sybase ASE: Использует аналогичный MS SQL синтаксис для UNION и UNION ALL. Поддержка INTERSECT и EXCEPT может требовать определенных настроек совместимости.

Основные отличия между платформами часто касаются обработки типов данных, сортировки NULL-значений и производительности при больших объемах информации.

Распространенные ошибки

Несовпадение числа столбцов в объединяемых запросах вызывает критическую ошибку.

SELECT ID, Имя FROM Сотрудники
UNION
SELECT ID FROM Клиенты; -- Ошибка
Сообщение 205, уровень 16, состояние 1
Все запросы в операторе UNION должны иметь равное число выражений в списке целей.

Несовместимость типов данных в соответствующих столбцах.

SELECT ДатаРождения FROM Сотрудники -- тип DATE
UNION
SELECT Имя FROM Клиенты; -- тип NVARCHAR. Ошибка.

Некорректное использование ORDER BY в отдельных запросах. ORDER BY применяется только к общему результату.

SELECT * FROM Таблица1 ORDER BY Поле1
UNION
SELECT * FROM Таблица2; -- ORDER BY в первом запросе не допускается

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

-- Медленнее, если дубликаты не важны
SELECT Город FROM Таблица1
UNION -- Выполняет лишнюю проверку на уникальность
SELECT Город FROM Таблица2;

Изменения в последних версиях

В SQL Server 2017 и более новых версиях существенных изменений синтаксиса оператора UNION не произошло. Основные улучшения касаются оптимизации производительности:

  • Улучшенный обработчик запросов эффективнее объединяет результаты при использовании UNION ALL с большим количеством ветвей.
  • Интеллектуальные функции обработки столбцов с разными типами данных, но совместимыми доменами.
  • Лучшая интеграция с системами обработки columnstore-индексов при объединении наборов данных.

Для использования актуальных возможностей оптимизации рекомендуется применять последние накопительные обновления SQL Server.

Расширенные примеры применения

Объединение данных из более чем двух источников с группировкой итогового результата:

Пример sql
SELECT Регион, SUM(Сумма) AS Общий_объем
FROM (
    SELECT Регион, Сумма FROM Продажи_2022
    UNION ALL
    SELECT Регион, Сумма FROM Продажи_2023
    UNION ALL
    SELECT Регион, Сумма FROM Продажи_2024
) AS Все_годы
GROUP BY Регион
HAVING SUM(Сумма) > 1000000;

Использование UNION внутри CTE (обобщенного табличного выражения) для рекурсивных запросов:

Пример sql
WITH Иерархия AS (
    SELECT ID, Имя, Родитель_ID, 1 AS Уровень
    FROM Сотрудники
    WHERE Родитель_ID IS NULL
    UNION ALL
    SELECT e.ID, e.Имя, e.Родитель_ID, h.Уровень + 1
    FROM Сотрудники e
    INNER JOIN Иерархия h ON e.Родитель_ID = h.ID
)
SELECT * FROM Иерархия;

Создание сводной таблицы с разметкой строки с помощью фиктивных столбцов:

Пример sql
SELECT ID, Имя, 'Активен' AS Статус FROM Сотрудники WHERE Активен = 1
UNION ALL
SELECT ID, Имя, 'Неактивен' FROM Сотрудники WHERE Активен = 0
ORDER BY Статус, Имя;
ID | Имя     | Статус
---|---------|---------
3  | Алексей | Активен
7  | Мария   | Активен
5  | Игорь   | Неактивен

Объединение результатов запросов с разными условиями фильтрации в одной таблице:

Пример sql
SELECT 'Высокий' AS Приоритет, COUNT(*) AS Количество FROM Заказы WHERE Сумма > 10000
UNION ALL
SELECT 'Средний', COUNT(*) FROM Заказы WHERE Сумма BETWEEN 5000 AND 10000
UNION ALL
SELECT 'Низкий', COUNT(*) FROM Заказы WHERE Сумма < 5000;

MS SQL UNION function comments

En
UNION Combines the results of two or more queries into a single result set