Обидва об'єднують результати кількох SELECT в один набір, один під одним.
UNION- прибирає дублікати: результат містить лише унікальні рядки.UNION ALL- залишає всі рядки як є, з повторами.
SELECT email FROM customers
UNION
SELECT email FROM newsletter_subscribers; -- кожен email один раз
SELECT 'order' AS type, id, created_at FROM orders
UNION ALL
SELECT 'refund', id, created_at FROM refunds -- усі події, повтори неможливі за змістом
ORDER BY created_at DESC;
Чому UNION ALL за замовчуванням краще: щоб прибрати дублікати, UNION змушений сортувати чи хешувати весь об'єднаний результат - на великих наборах це дорого (тимчасова таблиця, можливо, на диску). Якщо дублікатів бути не може (різні таблиці, різні типи подій) або вони потрібні, - UNION ALL.
Правила:
- Кількість колонок у всіх
SELECTоднакова; типи - сумісні. - Імена колонок результату беруться з першого
SELECT. ORDER BYіLIMITв кінці стосуються всього результату. Щоб відсортувати окрему частину, її беруть у дужки з власнимLIMIT.
Типові застосування: стрічка подій з кількох таблиць, пошук по кількох сутностях («знайти серед користувачів і компаній»), заміна складного OR на кілька простих запитів, кожен з яких використовує свій індекс:
SELECT * FROM users WHERE email = ?
UNION
SELECT * FROM users WHERE phone = ?;
У Laravel - ->union($query) і ->unionAll($query).