Your LEFT JOIN Became an INNER JOIN and Nothing Warned You
LEFT JOIN keeps every row from the left table and fills in NULL where nothing matches. But WHERE runs after the join, so any condition placed on a right-hand column also removes those NULL rows — and the LEFT JOIN becomes an INNER JOIN with no warning whatsoever. Measured on PostgreSQL 16: a plain LEFT JOIN gives 4 rows, adding WHERE leaves 2 rows, but moving that same condition into ON gives 3 rows — which is the correct answer.
This is the bug I see most often in reporting queries. It is not a syntax error, it is not slow, it throws nothing. It simply returns too few rows, and usually it is precisely the important ones that go missing: customers with no orders yet, products that have never sold, salespeople who have not closed anything.
This post drills into the JOIN lesson from my 30-day SQL series. Every number below is real output from PostgreSQL 16.11.
