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, стоил не одного дела. Проверьте свой запрос на архивном — там цена ошибки всего лишь потерянный вечер.