This is one of the queries:
select *
from t1 left join
t2
on t1.fid = t2.id left join
t3
on t2.fid = t3.id and t2.col = val;
Yes, the results are different. If you were using inner join they would be the same, but the left join changes things -- because the join clause does not do any filtering of rows.
I think the simplest explanation is that the join between t1 and t2 will include all rows from t1 as well as all matching rows from t2 -- even those where t2.col <> val. These remain in the result set, because the next left join does not filter them out.
In fact, the condition t2.col = val in the second on clause does not affect which rows are in the result set. If there is a match, then the row from t3 stays based on the first condition. If there is no match, then the row from t3 is still in the result set -- but the t3 columns will be NULL.
In this version:
select *
from t1 left join
t2
on t1.fid = t2.id and t2.col = val left join
t3
on t2.fid = t3.id;
The first join gets all rows from t1 and only matching rows from t2 where t2.col = val. The third join can then add more rows.
Note: there are definitely situations where the two queries would return the same results. But, the following data would generate different results (assume val = 0):
t1
fid
1
t2
fid col
1 0
1 1
t3
id
1
The query with the condition in the second on clause will return:
1 1 0 1
1 1 1 NULL
The query with the condition in the first on clause will return:
1 1 0 1