Как не потерять котят и не превратить LEFT JOIN в INNER случайно. Краткая сводка: существуют разные виды JOIN, в частности INNER и LEFT (есть и другие). JOIN нужны для соединения данных из разных таблиц.

Рассмотрим такой пример: у нас есть приют и 2 таблицы.

Таблица 1 (Имена) — номер домика и имя: 1 — Жожик, 2 — Барсик, 3 — Соня. Таблица 2 (Пол) — номер домика и пол: 1 — мальчик, 2 — мальчик, 3 — девочка.

Почему не объединить в одну таблицу — это уже вопрос про нормализацию данных, об этом в других заметках.

Так вот, мы хотим узнать имя и пол котика. Для этого нам нужно сделать INNER JOIN. На SQL это будет: FROM table1 t1 JOIN table2 t2 ON t1.num = t2.num. Это значит, мы берем значения из двух таблиц и соединяем их по номеру домика.

Но что, если появились новые котята и мы еще не знаем их пол? Пока мы можем им дать общее имя, но не пол. Итак в первой таблице пополнение: 4 — котенок 1, 5 — котенок 2. А во второй таблице 4 и 5 строка не существуют, потому что информации нет.

Теперь мы хотим узнать информацию по всем котикам. Если мы сделаем INNER JOIN, то не узнаем про котят, поэтому нам нужно сделать LEFT JOIN — это как бы INNER + оставшиеся строки из левой таблицы. Тогда мы получим: 1 — Жожа — мальчик 2 — Барсик — мальчик 3 — Соня — девочка 4 — котенок 1 — null 5 — котенок 2 — null

Но что если нам нужно посмотреть всех котиков, а пол только у мальчиков?

Если мы сделаем FROM ... LEFT JOIN ... WHERE sex = 'male', то у нас останется только: 1 — Жожа — мальчик 2 — Барсик — мальчик. Потому что остальные строки не соответствуют условию и отсекаются. Таким образом, мы делаем из LEFT JOIN неявно INNER. Правильно прописать условие в ON: FROM ... LEFT JOIN ON t1.num = t2.num AND sex = 'male'. Тогда у нас будет: 1 — Жожа — мальчик 2 — Барсик — мальчик 3 — Соня — null 4 — котенок 1 — null 5 — котенок 2 — null

Краткий вывод: Условие в ON — это фильтр для конкретной таблицы в процессе джойна. А WHERE — это фильтр уже всех таблиц после джойна.

Связи: 📌 Про то, как порядок выполнения запроса влияет на результат 📌 И снова про NULL


В этом посте были ссылки, но мы их удалили по правилам Сетки