Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
UNION в PostgreSQL
UNION — это оператор реляционной алгебры в PostgreSQL, предназначенный для объединения результатов двух или более SELECT-запросов в единый результирующий набор. Его ключевая особенность — удаление дублирующихся строк из финального результата, что делает его незаменимым инструментом для слияния данных из разных источников или таблиц.
Основная логика и синтаксис
Базовый синтаксис оператора UNION выглядит так:
SELECT column1, column2, ...
FROM table1
UNION
SELECT column1, column2, ...
FROM table2;
Критически важные правила применения:
- Количество и порядок столбцов в каждом
SELECTдолжно совпадать. - Типы данных соответствующих столбцов должны быть совместимы (PostgreSQL попытается выполнить неявное приведение типов, если это возможно).
- Имена столбцов в итоговом наборе берутся из первого запроса.
Пример использования UNION
Представим, у нас есть две таблицы с клиентами из разных регионов:
-- Клиенты из Москвы
CREATE TABLE customers_moscow (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100)
);
-- Клиенты из Санкт-Петербурга
CREATE TABLE customers_spb (
id SERIAL PRIMARY KEY,
full_name VARCHAR(100),
email VARCHAR(100)
);
Чтобы получить общий уникальный список email всех клиентов, применяем UNION:
SELECT email, name FROM customers_moscow
UNION
SELECT email, full_name FROM customers_spb;
Обратите внимание: хотя столбцы называются по-разному (name и full_name), их типы (VARCHAR) совместимы. В результате мы получим все уникальные email-адреса из обеих таблиц. Если один и тот же email встречается в обеих таблицах, в результат он попадёт только один раз.
Отличие UNION от UNION ALL
Это ключевой момент для понимания производительности. У UNION есть "брат" — оператор UNION ALL.
UNION: Выполняет сортировку и дедупликацию результата. Это дорогая операция, особенно на больших объёмах данных.UNION ALL: Просто соединяет все строки, включая дубликаты. Работает значительно быстрее.
-- Медленнее, но строки уникальны
SELECT id, name FROM table_a
UNION
SELECT id, name FROM table_b;
-- Быстрее, но могут быть дубликаты
SELECT id, name FROM table_a
UNION ALL
SELECT id, name FROM table_b;
Правило оптимизации: всегда используйте UNION ALL, если вам заранее известно, что дубликатов нет или их наличие допустимо для вашей задачи.
Сортировка и фильтрация с UNION
Операции ORDER BY и LIMIT применяются ко всему объединённому результату, а не к отдельным частям. ORDER BY должен ссылаться на столбцы итогового набора.
-- Получить топ-5 самых высокооплачиваемых сотрудников из двух департаментов
SELECT name, salary FROM developers
UNION
SELECT name, salary FROM managers
ORDER BY salary DESC -- Сортировка по итоговому набору
LIMIT 5;
Чтобы отсортировать или отфильтровать результаты каждого запроса по отдельности, используйте подзапросы или CTE (Common Table Expressions):
WITH devs AS (
SELECT name, salary, 'dev' as dept FROM developers ORDER BY salary DESC LIMIT 3
), mgrs AS (
SELECT name, salary, 'mgr' as dept FROM managers ORDER BY salary DESC LIMIT 3
)
SELECT * FROM devs
UNION ALL
SELECT * FROM mgrs;
Типичные сценарии применения UNION
- Консолидация данных из идентичных по структуре таблиц (шахтинг, партиционирование, архивные данные).
- Агрегация данных из разных, но совместимых источников (например, список пользователей из основной БД и импортированных из старой системы).
- Создание сводных отчётов, где данные для разных категорий считаются отдельными запросами.
- Эмуляция оператора
FULL OUTER JOINв некоторых специфичных случаях (через объединениеLEFTиRIGHT JOIN).
Внутренняя работа и производительность
С точки зрения плана выполнения (EXPLAIN), UNION реализуется через операции HashAggregate или Unique для удаления дубликатов, что требует дополнительной памяти и вычислений. UNION ALL часто сводится к простому Append узлу в плане, что объясняет его высокую скорость. При работе с большими данными или в условиях высоких нагрузок выбор между UNION и UNION ALL может иметь решающее значение для производительности всей системы.
Таким образом, UNION — это мощный и стандартизированный инструмент SQL, правильное использование которого требует понимания не только его синтаксиса, но и семантики (удаление дубликатов), а также его более производительной альтернативы — UNION ALL.