UNION vs UNION ALL — в чём разница и когда что использовать
Коротко
UNION объединяет результаты двух запросов и удаляет дубликаты. UNION ALL объединяет без удаления дубликатов. UNION ALL быстрее, потому что не тратит ресурсы на сортировку и дедупликацию.
Как работает UNION
UNION объединяет результаты двух SELECT-запросов в одну таблицу и автоматически убирает полностью совпадающие строки.
SELECT city FROM customers
UNION
SELECT city FROM suppliers;Если Москва есть и в customers, и в suppliers — в результате она появится один раз.
Под капотом UNION выполняет DISTINCT на объединённом результате. Это требует сортировки всех строк — отсюда дополнительная нагрузка.
Как работает UNION ALL
UNION ALL просто склеивает результаты двух запросов. Никакой проверки на дубликаты.
SELECT city FROM customers
UNION ALL
SELECT city FROM suppliers;Если Москва есть 3 раза в customers и 2 раза в suppliers — в результате будет 5 строк с Москвой.
Ключевые отличия
| UNION | UNION ALL | |
|---|---|---|
| Дубликаты | Удаляет | Оставляет |
| Производительность | Медленнее (сортировка + дедупликация) | Быстрее |
| Количество строк | ≤ сумма строк | = сумма строк |
| Когда использовать | Нужны уникальные значения | Нужны все строки или дубликатов точно нет |
Производительность
На больших данных разница существенная. UNION выполняет неявный DISTINCT — это сортировка или хеширование всего результата. Если в каждом запросе по миллиону строк, UNION ALL вернёт результат почти мгновенно, а UNION потратит время на дедупликацию.
Правило: используйте UNION ALL по умолчанию. Переключайтесь на UNION, только если вам действительно нужна дедупликация.
Требования к запросам
Оба оператора требуют:
- Одинаковое количество колонок в обоих SELECT
- Совместимые типы данных в соответствующих колонках
-- Ошибка: разное количество колонок
SELECT name, city FROM customers
UNION ALL
SELECT name FROM suppliers; -- не хватает колонкиПрактический пример: объединение событий
Типичная задача аналитика — собрать все события пользователя из разных таблиц:
SELECT user_id, 'purchase' AS event_type, created_at
FROM purchases
UNION ALL
SELECT user_id, 'login' AS event_type, created_at
FROM logins
UNION ALL
SELECT user_id, 'page_view' AS event_type, created_at
FROM page_views
ORDER BY user_id, created_at;Здесь UNION ALL правильный выбор: дубликатов быть не может (разные таблицы, разные события), и нам нужны все записи.
Вопросы с собеседований
- «Чем UNION отличается от JOIN?» — UNION складывает строки вертикально (добавляет строки). JOIN — горизонтально (добавляет колонки).
- «Когда UNION лучше UNION ALL?» — Только когда нужна дедупликация и вы уверены, что дубликаты возможны.
- «Можно ли использовать ORDER BY между UNION?» — Нет. ORDER BY применяется только к финальному результату, в самом конце.
FAQ
Можно ли объединить больше двух запросов?
Да, можно цепочкой: SELECT ... UNION ALL SELECT ... UNION ALL SELECT ... — без ограничений на количество.
UNION удаляет дубликаты по всем колонкам?
Да, строка считается дубликатом, только если все значения во всех колонках совпадают.
Что если типы данных не совпадают?
SQL попытается привести типы автоматически (implicit cast). Если не получится — ошибка. Лучше явно приводить типы через CAST.