Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

T-SQL: Additional predicates on JOINs vs. the WHERE clause

Tags:

sql

tsql

Is there any difference between putting additional predicates on a JOIN statement vs. adding them as additional clauses in the WHERE statement?

Example 1: Predicate on the WHERE clause

select emp.*
from Employee emp
left join Order o on emp.Id = o.EmployeeId
where o.Cancelled = 0

Example 2: Predicate on the JOIN statement

select emp.*
from Employee emp
left join Order o on emp.Id = o.EmployeeId and o.Cancelled = 0
like image 637
Neil Barnwell Avatar asked Sep 07 '11 10:09

Neil Barnwell


People also ask

Which is faster condition in join or WHERE clause?

I ran some tests and the results show that it is actually very close, but the WHERE clause is actually slightly faster! =) I absolutely agree that it makes more sense to apply the filter on the WHERE clause, I was just curious as to the performance implications.

Are joins more efficient than WHERE?

“Is there a performance difference between putting the JOIN conditions in the ON clause or the WHERE clause in MySQL?” No, there's no difference. The following queries are algebraically equivalent inside MySQL and will have the same execution plan.

What is the difference between WHERE clause and join?

One difference is that the first option hides the intent by expressing the join condition in the where clause. The second option, where the join condition is written out is more clear for the user reading the query. It shows the exact intent of the query.

Can we use join and WHERE clause together?

To use the WHERE clause to perform the same join as you perform using the INNER JOIN syntax, enter both the join condition and the additional selection condition in the WHERE clause. The tables to be joined are listed in the FROM clause, separated by commas. This query returns the same output as the previous example.


3 Answers

With the first statement the outer join is effectively turned into an inner join because of the WHERE condition as it will filter out all rows from the employee table where no order was found (because o.Cancelled will be NULL then)

So the two statements don't do the same thing.

like image 56
a_horse_with_no_name Avatar answered Sep 19 '22 14:09

a_horse_with_no_name


I already got the answers from some of my colleagues, but in case they don't post it here, I'll add an answer myself.

Both of these examples assume that the predicate is comparing a column on the "right" table with a scalar value.

Performance
It seems that if the predicate is on the JOIN, then the "right" table is filtered in advance. If the predicate is part of the WHERE clause, then all results come back and are filtered once at the end before returning the resultset.

Data Returned
if the predicate is part of the WHERE clause, then in the situation where the "right" value is null (i.e. there is no joining row) then the entire row will not be returned in the final resultset, because the predicate will compare the value with null and therefore return false.

like image 36
Neil Barnwell Avatar answered Sep 23 '22 14:09

Neil Barnwell


Just to address the case that the additional predicate is on a column from the left hand table this can still make a difference as shown below.

WITH T1(N) AS
(
SELECT 1 UNION ALL
SELECT 2
), T2(N) AS
(
SELECT 1 UNION ALL
SELECT 2
)
SELECT T1.N, T2.N, 'ON' AS Clause
FROM T1 
LEFT JOIN T2 ON T1.N = T2.N AND T1.N=1
UNION ALL
SELECT T1.N, T2.N, 'WHERE' AS Clause
FROM T1 
LEFT JOIN T2 ON T1.N = T2.N 
WHERE T1.N=1

Returns

N           N           Clause
----------- ----------- ------
1           1           ON
2           NULL        ON
1           1           WHERE
like image 31
Martin Smith Avatar answered Sep 22 '22 14:09

Martin Smith