SELECT
a.foo
b.bar
c.foobar
FROM tableOne AS a
INNER JOIN tableTwo AS b ON a.pk = b.fk
LEFT JOIN tableThree AS c ON b.pk = c.fk
WHERE a.foo = \'something\'
AND c.foo
The LEFT JOIN produces NULLs where there are no matching rows. In this case, c.foobar will be NULL for the non-matching rows. But your WHERE clause is looking for a specific value: 'somethingelse', and so will filter out all the NULL values. Since an INNER JOIN also produces no NULL values on the right side, the two look the same. You can add ' OR c.foobar IS NULL' to allow the null values back in.
When you move the condition to the ON clause, it becomes part of the JOIN row matching, rather than the final filter. The join match may fail, and the outer join then returns NULLs on cases where 'c.foobar' is NULL or not 'somethingelse'.
See