What is the difference between these two statements?
SELECT * FROM Cars c INNER JOIN Resellers r ON c.CarId = r.CarId AND c.Engine = "V8"
And the following query?
SELECT * FROM Cars c INNER JOIN Resellers r ON c.CarId = r.CarId WHERE c.Engine = 'V8'
As you can see, both above queries return a join of cars and resellers for V8 cars. And obviously both queries will return same results. But does it mean that there is no difference between these two way of limiting the results by conditions?
Although for inner join you can use both approaches interchangeably, for outer join a subtle difference can catch you. What would you expect to be the outcome of the following query?
SELECT * FROM Cars c LEFT JOIN Resellers r ON c.CarId = r.CarId AND c.Engine = "V8"
If you expect to get all the cars with V8 engine left joined to the resellers, you won’t be happy with the result because if there is a car that is not a V8 but has no resellers, will be reflected in the results! You have to move c.Engine=’V8′ to the WHERE clause to guarantee the correct behaviour..
SELECT * FROM Cars c LEFT JOIN Resellers r ON c.CarId = r.CarId WHERE c.Engine = "V8"
Reason for this behaviour is that Sql Server will first apply the outer join predicates and then reverts rows that have no right side representation. To understand the condition better, think about the way you write a left join in Linq.
var res = from c in Cars join rs in Resellers on c.CarId equals rs.CarId from r in rs.DefaultIfEmpty() select ...;
Left join in Sql server is also calculated the same way. In the above example you first run the join between Cars and Resellers, then select Null when the resellers collection is empty for the join (i.e. rs.DefaultIfEmpty()).