В чем разница JOIN и UNION в SQL
Что проверяют
Базовое понимание того, в каком направлении каждая операция склеивает данные. Следом обычно спрашивают разницу UNION и UNION ALL, а Java-разработчика ещё и о том, как это выразить в JPA или Hibernate.
Как отвечать
Короткая формула: JOIN соединяет таблицы по горизонтали и добавляет колонки, UNION складывает результаты запросов по вертикали и добавляет строки.
- JOIN: сопоставляет строки двух таблиц по условию в
ON. Виды:INNER(только совпавшие),LEFTиRIGHT(все строки одной стороны, у другойNULL),FULL(все с обеих сторон),CROSS(декартово произведение). При связи один ко многим строки размножаются: клиент с пятью заказами даст пять строк; - UNION: объединяет результаты нескольких
SELECT. Число колонок должно совпадать, типы должны быть совместимы, сопоставление идёт по позиции, имена колонок берутся из первого запроса; - UNION и UNION ALL:
UNIONубирает дубли, для этого базе нужна сортировка или хэширование всего результата.UNION ALLпросто склеивает и работает быстрее; - ORDER BY и LIMIT в
UNIONприменяются к итоговому набору, если не взять части в скобки.
Примеры задач: JOIN для «заказы вместе с именем клиента», UNION ALL для «общая лента событий из таблиц платежей и возвратов».
В Java-стеке JOIN в JPQL идёт по связям сущностей, а JOIN FETCH подтягивает коллекцию одним запросом и спасает от проблемы N+1. UNION в HQL поддерживается начиная с Hibernate 6, в более старом коде для него писали нативный запрос через @Query(nativeQuery = true) в Spring Data.
Где спотыкаются
Считают JOIN и UNION взаимозаменяемыми. Они решают разные задачи, и ответ «оба объединяют таблицы» интервьюера не устроит.
Пишут UNION по привычке там, где хватает UNION ALL, и платят лишней сортировкой на больших выборках.
Не замечают, что UNION сопоставляет колонки по порядку, а не по имени. Если в одном запросе name, city, а в другом city, name, запрос выполнится без ошибки и перемешает данные.