LEFT JOIN, ставший INNER: WHERE после JOIN

Вы берёте LEFT JOIN — специально, чтобы не потерять тех, у кого во втором журнале ничего нет.

SELECT v.person_id, p.amount
FROM visits v
LEFT JOIN bills p ON v.person_id = p.person_id
WHERE p.amount > 0;

Результат — как будто вы взяли обычный INNER JOIN. Все, кого LEFT должен был спасти, из выдачи снова пропали.

«LEFT JOIN даёт слово каждому. WHERE решает, кого дослушать до конца — и решает уже после того, как слово дали.»

Почему LEFT не спас никого?

Условие на столбец правой таблицы в WHERE выполняется ПОСЛЕ соединения — а у сирот без пары этот столбец пуст (NULL), и «amount > 0» на пустоте не срабатывает никогда. Ровно те строки, ради которых брали LEFT, и вылетают.

Лечение: условие на правую таблицу переносится в само условие соединения — ON, а не в WHERE.

SELECT v.person_id, p.amount
FROM visits v
LEFT JOIN bills p
  ON v.person_id = p.person_id AND p.amount > 0;
-- фильтр внутри ON — LEFT остаётся LEFT
«Условие на правой таблице переезжает в ON. WHERE трогает её, только если ищете как раз тех, у кого пары нет вовсе.»

LEFT, ставший INNER, стоил не одного дела. Проверьте свой запрос на архивном — там цена ошибки всего лишь потерянный вечер.

$0
тащи карточки за верхнюю кромку · «+ стикер» · «🧵 нить» — клик по двум

ЛОТОК УЛИК

во вкладке SQL найди подозреваемых и жми «+ доска»

НА ПРОВЕРКУ

теории из «Заметок» отправляются сюда — подтверди на доске или удали
Ctrl+Enter · «+ доска» на строке — выбрать поля и перенестипиши запрос, я подожду
Результат появится здесь.

Картотека

Заметки

Факты

Теории на проверку

Подсказки

◆ РЕЖИМ АРХИВАРИУСАуправление картотекой дел · не виден игроку