Разберем, почему происходит различие между двумя запросами с LEFT JOIN, где условие включено в разные части: ON и WHERE.
Такое встречается на тестовых. Ну и по работе тоже нужно конечно.
Есть две таблицы: Таблица 1: информация о транзакциях и Таблица 2: информация о типе пользователя
Задача: выполнить LEFT JOIN по user_id, чтобы узнать, какой у пользователя тип (type), и разобраться, почему два похожих запроса могут дать разные результаты.
🟢 Запрос 1️⃣: LEFT JOIN с условием в ON:
SELECT df_1.user_id, df_1.amount, df_2.type
FROM df_1
LEFT JOIN df_2 ON df_1.user_id = df_2.user_id AND df_2.type = 'admin'
Для каждой строки из df_1 ищется строка в df_2, где user_id совпадают и type в df_2 равно 'admin'.
Если такое совпадение найдено, строка из df_2 включается в результат. Если совпадений нет, то столбцы из df_2 заполняются NULL.
Все строки из df_1 присутствуют, так как это LEFT JOIN.
🟢 Запрос 2️⃣: LEFT JOIN с условием в WHERE
SELECT df_1.user_id, df_1.amount, df_2.type
FROM df_1
LEFT JOIN df_2 ON df_1.user_id = df_2.user_id
WHERE df_2.type = 'admin'
Аналогично предыдущему случаю, LEFT JOIN возвращает все строки из df_1 и соответствующие строки из df_2.
Условие WHERE отфильтровывает строки после объединения. Это означает, что оно удалит все строки, где df_2.type не равно 'admin' и также строки, где df_2.type равно NULL.
В результате будут включены только строки, где df_2.type = 'admin'.
🤓 В чем разница?
Условие в ON позволяет выполнить фильтрацию во время объединения (JOIN), сохраняя все строки из левой таблицы (df_1) и вставляя NULL для несоответствующих значений из правой таблицы.
Условие в WHERE применяется после объединения. Поэтому строки, которые не соответствуют условию (type = 'admin'), будут удалены включая строки с NULL!
💡 Запомним 🚀
ON — фильтрует при объединении, сохраняя строки из левой таблицы.
WHERE — фильтрует после объединения, убирая строки с NULL и несоответствующими значениями.
p.s. Картинку рисовала в Canva впервые. Накидайте реакций за смелость :) Дизайнерам тапками не кидаться, сделала как смогла 😂
