В чем разница cross join и right join
Что проверяют
Понимаете ли вы, что эти соединения решают разные задачи: CROSS JOIN перемножает таблицы без условия, RIGHT JOIN сохраняет все строки правой таблицы. Следом часто просят переписать RIGHT JOIN через LEFT или спрашивают, откуда в запросе через Hibernate взялось размножение строк.
Как отвечать
- CROSS JOIN: каждая строка первой таблицы соединяется с каждой строкой второй, условия
ONнет. Изmиnстрок получаетсяm × n, а если одна из таблиц пустая, результат тоже пустой. Эквивалентные записи:FROM a, bбезWHEREиJOIN ... ON TRUE; - RIGHT JOIN: соединение по условию, в результат попадают все строки правой таблицы, а там, где пары слева нет, колонки левой таблицы заполняются
NULL.A RIGHT JOIN Bэто то же самое, чтоB LEFT JOIN A, поэтому на практике почти везде пишут LEFT: запрос читается от главной таблицы слева направо.
Где что применяется. CROSS JOIN нужен для комбинаций: размеры на цвета или сетка «сотрудник на каждый день месяца», к которой потом через LEFT JOIN подтягиваются факты, чтобы увидеть дни без записей. RIGHT JOIN, как и LEFT, ищет строки без пары: например, категории без единого товара, через IS NULL на ключе второй таблицы.
Для Java-разработчика стоит добавить про JPA. В JPQL две сущности через запятую во FROM дают то же декартово произведение, а условие связи уходит в WHERE. Стандарт JPQL обязывает поддерживать только внутреннее соединение и LEFT JOIN, RIGHT JOIN зависит от провайдера, HQL в Hibernate его понимает. Ещё один источник размножения строк: несколько JOIN FETCH по коллекциям в одном запросе, из-за чего для двух списков Hibernate выбрасывает MultipleBagFetchException.
Где спотыкаются
Ставят условие на колонку левой таблицы в WHERE после RIGHT JOIN. Строки с NULL отсеиваются, и соединение молча превращается во внутреннее. Такому условию место в ON.
Называют CROSS JOIN бесполезным или не могут оценить объём: две таблицы по 10 тысяч строк дают 100 миллионов.
Считают, что RIGHT JOIN возвращает строки без пары с обеих сторон. Это делает FULL OUTER JOIN.