T-SQL:JOIN与WHERE子句的附加谓词

时间:2011-09-07 10:16:22

标签: sql tsql

在JOIN语句上添加其他谓词与在WHERE语句中将它们添加为附加子句之间是否有任何区别?

示例1:WHERE子句的谓词

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

示例2:JOIN语句的谓词

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

4 个答案:

答案 0 :(得分:9)

使用第一个语句,由于WHERE条件,外连接被有效地转换为内连接,因为它将过滤掉没有找到订单的employee表中的所有行(因为o.Cancelled将为NULL)

所以这两个陈述没有做同样的事情。

答案 1 :(得分:4)

我已经得到了一些同事的答案,但是如果他们不在这里发布,我会自己添加一个答案。

这两个例子都假设谓词正在将“右”表中的列与标量值进行比较。

<强>性能
似乎如果谓词在JOIN上,那么“右”表将被提前过滤。如果谓词是WHERE子句的一部分,那么所有结果都会返回并在返回结果集之前在结束时过滤一次。

返回的数据
如果谓词是WHERE子句的一部分,那么在“right”值为null(即没有连接行)的情况下,整行将不会返回最终结果集,因为谓词会将值与null进行比较,因此返回false。

答案 2 :(得分:3)

为了解决附加谓词位于左侧表格列中的情况,这仍然可以产生差异,如下所示。

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

返回

N           N           Clause
----------- ----------- ------
1           1           ON
2           NULL        ON
1           1           WHERE

答案 3 :(得分:0)

这是另一个例子(四个案例)

insert into #tmp(1,"A")
insert into #tmp(2,"B")

select "first Query", a.*,b.* from #tmp a LEFT JOIN #tmp b
on a.id =b.id
and  a.id =1

union all

select "second Query", a.*,b.* from #tmp a LEFT JOIN #tmp b
on a.id =b.id
where a.id =1

union all

select "Third Query", a.*,b.* from #tmp a LEFT JOIN #tmp b
on a.id =b.id
and  b.id =1

union all

select "Fourth Query", a.*,b.* from #tmp a LEFT JOIN #tmp b
on a.id =b.id
where  b.id =1

结果:

first Query       1      A      1      A
first Query       2      B      NULL   NULL
second Query      1      A      1      A
Third Query       1      A      1      A
Third Query       2      B      NULL   NULL
Fourth Query      1      A      1      A
Fourth Query      1      A      1      A