← Назад к вопросам

В чём разница между UNION и UNION ALL?

1.0 Junior🔥 201 комментариев
#SQL и базы данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

UNION vs UNION ALL: объединение результатов запросов

UNION и UNION ALL — это операции для объединения результатов двух или более SELECT запросов в один результат.

Основная разница: UNION удаляет дубликаты, UNION ALL сохраняет все.

Простой пример

-- Таблица 1: Текущие сотрудники
SELECT name, department
FROM current_employees;

Результат:
name    | department
Alice   | Sales
Bob     | Engineering
Charlie | Sales

-- Таблица 2: Бывшие сотрудники
SELECT name, department
FROM former_employees;

Результат:
name    | department
Diana   | Sales
Eric    | Engineering
Alice   | Sales  ← Эта Alice была раньше

-- Теперь объединяю:

SELECT name, department FROM current_employees
UNION
SELECT name, department FROM former_employees;

Результат (Alice одна раз, потому что UNION удаляет дубликаты):
name    | department
Alice   | Sales      ← одна строка
Bob     | Engineering
Charlie | Sales
Diana   | Sales
Eric    | Engineering

Всего: 5 строк
-- Тот же запрос с UNION ALL

SELECT name, department FROM current_employees
UNION ALL
SELECT name, department FROM former_employees;

Результат (Alice два раза):
name    | department
Alice   | Sales
Bob     | Engineering
Charlie | Sales
Diana   | Sales
Eric    | Engineering
Alice   | Sales      ← вторая Alice

Всего: 6 строк

Таблица сравнения

ПараметрUNIONUNION ALL
ДубликатыУдаляетСохраняет
ПроизводительностьМедленнее (нужно сортировать для удаления дубликатов)Быстрее
Когда использоватьКогда нужны уникальные значенияКогда нужны все значения

Когда использовать UNION

UNION используй когда нужны УНИКАЛЬНЫЕ значения:

-- Пример: найти всех пользователей которые либо сделали покупку,
-- либо зарегистрировались в приложении

SELECT user_id FROM orders
UNION
SELECT user_id FROM app_registrations;

-- Если user_id в обеих таблицах, он появится один раз
-- Результат: список уникальных пользователей

Техническая реализация:

Шаг 1: Выполню первый SELECT
Шаг 2: Выполню второй SELECT
Шаг 3: Объединю результаты
Шаг 4: Отсортирую и удалю дубликаты (expensive!)

Когда использовать UNION ALL

UNION ALL используй когда дубликаты важны или нужна скорость:

-- Пример: объединить логи ошибок из разных систем

SELECT error_id, error_msg, timestamp FROM system_a_errors
UNION ALL
SELECT error_id, error_msg, timestamp FROM system_b_errors
UNION ALL
SELECT error_id, error_msg, timestamp FROM system_c_errors;

-- Мне нужны ВСЕ ошибки из всех систем
-- Если система выдала одну и ту же ошибку дважды, это важно
-- UNION ALL будет быстрее

Практические примеры

Пример 1: Объединение данных из разных источников

-- Продажи из разных магазинов
SELECT 
  order_id,
  customer_id,
  amount,
  'store_a' as source
FROM store_a_orders
WHERE date >= '2024-01-01'

UNION ALL  ← использую UNION ALL потому что нужны все продажи

SELECT 
  order_id,
  customer_id,
  amount,
  'store_b' as source
FROM store_b_orders
WHERE date >= '2024-01-01'

UNION ALL

SELECT 
  order_id,
  customer_id,
  amount,
  'store_c' as source
FROM store_c_orders
WHERE date >= '2024-01-01';

-- Результат: все продажи из всех магазинов

Пример 2: Объединение с фильтрацией дубликатов

-- Какие email'ы используются дважды? (в current и legacy базе)

SELECT email
FROM current_users
WHERE email IN (
  SELECT email
  FROM legacy_users
)

-- Другой способ через UNION
SELECT DISTINCT email  ← фильтрую дубликаты после
FROM (
  SELECT email FROM current_users
  UNION ALL
  SELECT email FROM legacy_users
) combined
GROUP BY email
HAVING COUNT(*) > 1;  ← появляются больше одного раза

Пример 3: Комбинирование разных типов запросов

-- Объединить информацию о пользователях и гостях

SELECT 
  user_id,
  'user' as type,
  email,
  created_at
FROM users

UNION

SELECT 
  guest_id,
  'guest' as type,
  email,
  created_at
FROM guests;

-- Если пользователь и гость используют один email,
-- он появится один раз с первого SELECT

Требования к UNION

1. Одинаковое количество колонок

-- ✅ ПРАВИЛЬНО
SELECT id, name FROM users
UNION
SELECT id, name FROM archived_users;  ← 2 колонки в обоих

-- ❌ НЕПРАВИЛЬНО
SELECT id, name, email FROM users
UNION
SELECT id, name FROM archived_users;  ← 3 vs 2 колонок

2. Совместимые типы данных

-- ✅ ПРАВИЛЬНО
SELECT user_id (INT), email (VARCHAR) FROM users
UNION
SELECT customer_id (INT), email (VARCHAR) FROM customers;

-- ❌ НЕПРАВИЛЬНО
SELECT user_id (INT), email (VARCHAR) FROM users
UNION
SELECT email (VARCHAR), user_id (INT) FROM others;  ← порядок важен!

Производительность

-- Тест на 1M строк

SELECT id, amount FROM table_a
UNION
SELECT id, amount FROM table_b;
-- Время: 2.5 сек
-- Операции: scan + sort + distinct (дорого!)

SELECT id, amount FROM table_a
UNION ALL
SELECT id, amount FROM table_b;
-- Время: 0.8 сек (3x быстрее!)
-- Операции: scan + scan (просто соединение)

Правило: Используй UNION ALL по умолчанию, UNION только если нужны уникальные значения.

Альтернатива UNION — CONCAT или JOIN

-- Вместо UNION для объединения похожих таблиц

-- Способ 1: UNION (выше)
SELECT * FROM users
UNION ALL
SELECT * FROM archived_users;

-- Способ 2: FULL OUTER JOIN (если есть общий key)
SELECT COALESCE(u.id, a.id) as id,
       u.name as current_name,
       a.name as archived_name
FROM users u
FULL OUTER JOIN archived_users a ON u.id = a.id;

-- Способ 3: CTE (более читаемо)
WITH all_users AS (
  SELECT * FROM users
  UNION ALL
  SELECT * FROM archived_users
)
SELECT * FROM all_users WHERE ...;

Вывод

UNION vs UNION ALL:

  • UNION — удаляет дубликаты (медленнее, безопаснее)
  • UNION ALL — сохраняет все (быстрее, может быть дубликаты)

Когда использовать:

  • UNION: дважды нужны уникальные значения
  • UNION ALL: объединение всех данных из разных источников

Памятка:

Если сомневаешься → использови UNION ALL
Это быстрее, и ты всегда можешь добавить DISTINCT после если нужно.

SELECT DISTINCT ... FROM (
  SELECT * FROM table1
  UNION ALL
  SELECT * FROM table2
);

Производительность: UNION ALL в 3-10x быстрее UNION на большых объёмах, потому что не требует sorting и duplicate detection.

В чём разница между UNION и UNION ALL? | PrepBro