UNION и UNION ALL

UNION складывает результаты запросов вертикально. Ветви должны возвращать одинаковое число столбцов с совместимыми типами.

SELECT id, user_id, total, 'current' AS source
FROM orders
WHERE created_at >= TIMESTAMP '2026-01-01 00:00:00'
 
UNION ALL
 
SELECT id, user_id, total, 'archive' AS source
FROM archived_orders
WHERE created_at >= TIMESTAMP '2026-01-01 00:00:00';

UNION или UNION ALL

  • UNION ALL сохраняет все строки.
  • UNION удаляет полные дубликаты итоговых строк.

Удаление дубликатов требует дополнительной работы — обычно сортировки или хеширования. Если ветви гарантированно не пересекаются или дубликаты имеют смысл, выбирают UNION ALL.

Имена, типы и сортировка

Имена столбцов результата обычно берутся из первой ветви. Общий ORDER BY относится ко всему объединению:

SELECT id, created_at FROM orders
UNION ALL
SELECT id, created_at FROM archived_orders
ORDER BY created_at DESC, id DESC;

Локальный ORDER BY внутри ветви без локального ограничения обычно не определяет порядок объединенного результата.

Где ставить общий фильтр

Если один предикат должен применяться ко всем ветвям, его можно повторить в каждой ветви или обернуть объединение:

SELECT *
FROM (
    SELECT id, user_id, total FROM orders
    UNION ALL
    SELECT id, user_id, total FROM archived_orders
) AS all_orders
WHERE total >= 1000;

Внешняя форма уменьшает риск забыть ветвь. Оптимизатор часто проталкивает безопасный фильтр внутрь, но это проверяют планом. Реальный пример ошибки: Кейс фильтр поверх UNION.

Ловушки

  • UNION сравнивает все выбранные столбцы: технический столбец source не даст строкам считаться дубликатами.
  • Не следует маскировать неправильный JOIN с помощью UNION или DISTINCT.
  • Неявное приведение типов может ухудшить план или изменить точность.
  • UNION объединяет наборы строк, а JOIN — столбцы связанных строк.

Связано: Теория множеств, Запрос из 2х таблиц, SQL оценка производительности.

Вопросы

Что быстрее: UNION или UNION ALL? Обычно UNION ALL, потому что не удаляет дубликаты.

Где действует ORDER BY после последней ветви? На весь составной результат.

Когда нужен внешний фильтр? Когда единое условие должно гарантированно применяться ко всем ветвям.

Совпадает ли UNION с JOIN? Нет: первый добавляет строки, второй сопоставляет строки и добавляет столбцы.