UNION и UNION ALL — операторы SQL, которые объединяют результаты двух (или больше) запросов SELECT в один набор строк. Разница между ними в одном: UNION убирает полностью одинаковые строки из итогового результата (аналог SELECT DISTINCT над объединением), а UNION ALL оставляет все строки как есть, включая дубликаты. UNION ALL работает быстрее UNION, потому что не тратит время на сравнение и удаление дубликатов.
UNION vs UNION ALL:
— Дубликаты строк. UNION — удаляются. UNION ALL — остаются все.
— Скорость. UNION медленнее (есть доп. шаг сортировки/хеширования). UNION ALL быстрее (доп. шага нет).
— Что делает под капотом. UNION сравнивает строки и убирает полные дубликаты (аналог DISTINCT). UNION ALL просто складывает результаты обоих запросов друг за другом.
— Когда использовать. UNION — дубликаты реально возможны и их нужно убрать. UNION ALL — дубликатов не будет по логике данных или они не важны для задачи.
UNION vs UNION ALL:
— Дубликаты строк. UNION — удаляются. UNION ALL — остаются все.
— Скорость. UNION медленнее (есть доп. шаг сортировки/хеширования). UNION ALL быстрее (доп. шага нет).
— Что делает под капотом. UNION сравнивает строки и убирает полные дубликаты (аналог DISTINCT). UNION ALL просто складывает результаты обоих запросов друг за другом.
— Когда использовать. UNION — дубликаты реально возможны и их нужно убрать. UNION ALL — дубликатов не будет по логике данных или они не важны для задачи.
В чём разница между UNION и UNION ALL на примере?
SELECT city FROM offices
UNION
SELECT city FROM warehouses;
UNION
SELECT city FROM warehouses;
SELECT city FROM offices
UNION ALL
SELECT city FROM warehouses;
UNION ALL
SELECT city FROM warehouses;
Если в offices и warehouses есть строка с городом 'Москва' в обеих таблицах, запрос с UNION вернёт 'Москва' один раз, а запрос с UNION ALL — два раза (по одному разу из каждой таблицы). Оба запроса объединяют результаты двух SELECT в один список — разница только в обработке дубликатов.
Какие условия должны выполняться, чтобы использовать UNION и UNION ALL?
SELECT id, name, 'офис' AS source FROM offices
UNION ALL
SELECT id, name, 'склад' AS source FROM warehouses;
UNION ALL
SELECT id, name, 'склад' AS source FROM warehouses;
Оба запроса, объединяемые через UNION/UNION ALL, должны возвращать одинаковое количество столбцов, а типы данных в соответствующих столбцах должны быть совместимы (СУБД может привести их к общему типу, но не любые типы совместимы между собой). Названия столбцов итогового результата берутся из первого SELECT — псевдонимы во втором и последующих запросах на итоговые названия столбцов не влияют. В примере добавлен литеральный столбец 'офис'/'склад' — так удобно помечать, из какой исходной таблицы взята каждая строка после объединения.
Почему UNION ALL быстрее, чем UNION?
UNION после объединения строк выполняет дополнительный шаг — сортировку или хеширование всего результата, чтобы найти и убрать полные дубликаты, это соответствует операции, похожей на DISTINCT. UNION ALL этот шаг пропускает полностью — просто складывает результаты обоих запросов друг за другом. На больших наборах данных разница в производительности может быть заметной. Правило: если точно известно, что дубликатов не будет (например, объединяются данные за непересекающиеся периоды времени или из взаимоисключающих категорий), или если дубликаты не важны для задачи — используйте UNION ALL. UNION нужен только тогда, когда дубликаты реально возможны и их обязательно нужно убрать.
Как использовать ORDER BY с UNION и UNION ALL?
SELECT city FROM offices
UNION
SELECT city FROM warehouses
ORDER BY city;
UNION
SELECT city FROM warehouses
ORDER BY city;
ORDER BY в запросе с UNION/UNION ALL пишется один раз, в самом конце, и сортирует уже объединённый итоговый результат — сортировку нельзя применить к каждому SELECT отдельно перед объединением (в большинстве СУБД ORDER BY разрешён только в последнем SELECT перед итоговым результатом и относится ко всему объединению, а не к отдельному запросу).
Частые вопросы про UNION и UNION ALL
UNION и UNION ALL — это то же самое, что JOIN? Нет. JOIN соединяет строки из двух таблиц по столбцам «в ширину» (добавляет столбцы одной таблицы к строкам другой по условию совпадения). UNION/UNION ALL складывает результаты запросов «в высоту» (добавляет строки одного результата под строки другого) — это два принципиально разных вида объединения.
Можно ли объединить через UNION таблицы с разным числом столбцов? Нет, напрямую нельзя — количество столбцов в каждом SELECT должно совпадать. Если в одной из таблиц нужного столбца нет, его можно подставить как константу или NULL с явным приведением типа, чтобы количество и типы столбцов совпали.
Что быстрее — UNION или объединение через WHERE с OR? Иногда UNION ALL над двумя отдельными индексируемыми условиями быстрее одного запроса с OR в WHERE, потому что оптимизатор может использовать разные индексы для каждой части UNION ALL по отдельности, тогда как OR в одном WHERE иногда мешает оптимизатору использовать индекс эффективно. Но это зависит от конкретной СУБД, данных и плана выполнения — универсального правила нет, нужно проверять через EXPLAIN.
Нужно ли писать UNION DISTINCT? UNION без дополнительных слов уже подразумевает удаление дубликатов — UNION DISTINCT означает то же самое и является более явной формой записи. Поддерживается в PostgreSQL и MySQL, но не во всех СУБД (например, в SQLite такого синтаксиса нет) — писать его не обязательно, обычный UNION работает одинаково.
Можно ли объединить через UNION таблицы с разным числом столбцов? Нет, напрямую нельзя — количество столбцов в каждом SELECT должно совпадать. Если в одной из таблиц нужного столбца нет, его можно подставить как константу или NULL с явным приведением типа, чтобы количество и типы столбцов совпали.
Что быстрее — UNION или объединение через WHERE с OR? Иногда UNION ALL над двумя отдельными индексируемыми условиями быстрее одного запроса с OR в WHERE, потому что оптимизатор может использовать разные индексы для каждой части UNION ALL по отдельности, тогда как OR в одном WHERE иногда мешает оптимизатору использовать индекс эффективно. Но это зависит от конкретной СУБД, данных и плана выполнения — универсального правила нет, нужно проверять через EXPLAIN.
Нужно ли писать UNION DISTINCT? UNION без дополнительных слов уже подразумевает удаление дубликатов — UNION DISTINCT означает то же самое и является более явной формой записи. Поддерживается в PostgreSQL и MySQL, но не во всех СУБД (например, в SQLite такого синтаксиса нет) — писать его не обязательно, обычный UNION работает одинаково.
Закрепить UNION и UNION ALL на практике
Разница между UNION и UNION ALL кажется мелочью, пока не запустишь EXPLAIN на большой таблице и не увидишь лишний шаг сортировки и дедупликации. Проверить это на собственном опыте, а заодно потренироваться выбирать между UNION ALL и OR в WHERE для конкретного плана выполнения, можно на тренажёре SQL Arena от Quality Academy — задачи с реальным EXPLAIN, переключением диалекта и AI-ментором. Больше 800 задач, часть — бесплатно.
-------
Полезные ссылки школы
Сайт Quality Academy:
https://quality-academy.ru/main
Telegram-канал:
https://t.me/quality_academy
YouTube-канал:
https://www.youtube.com/@quality_academy
ВКонтакте:
https://vk.com/quality_academy
Канал отзывов учеников (58+ отзывов):
https://t.me/quality_academy_reviews
Задать вопрос менеджеру:
https://t.me/quality_academy_bot
Тест «Подойдёт ли вам тестирование»:
https://quiz.quality-academy.ru
5000+ вопросов с собесов тестировщика — бот-тренажёр:
https://t.me/quality_academy_interview_bot
3 практические задачи и дорожная карта:
https://t.me/quality_academy_tasks_bot
Бесплатные тренажёры — SQL Arena, Playwright Arena, Python Arena:
SQL Arena · Playwright Arena · Python Arena
https://quality-academy.ru/main
Telegram-канал:
https://t.me/quality_academy
YouTube-канал:
https://www.youtube.com/@quality_academy
ВКонтакте:
https://vk.com/quality_academy
Канал отзывов учеников (58+ отзывов):
https://t.me/quality_academy_reviews
Задать вопрос менеджеру:
https://t.me/quality_academy_bot
Тест «Подойдёт ли вам тестирование»:
https://quiz.quality-academy.ru
5000+ вопросов с собесов тестировщика — бот-тренажёр:
https://t.me/quality_academy_interview_bot
3 практические задачи и дорожная карта:
https://t.me/quality_academy_tasks_bot
Бесплатные тренажёры — SQL Arena, Playwright Arena, Python Arena:
SQL Arena · Playwright Arena · Python Arena