WHERE子句中的过滤与ON子句之间的区别是什么?

时间:2013-10-03 08:21:43

标签: sql tsql sql-server-2012

我想知道在使用WHERE子句或在内连接的ON中使用匹配是否有任何区别。

这种情况下的结果是一样的。

首先查询:

with Catmin as 
(
    select categoryid, MIN(unitprice) as mn
    from production.Products
    group by categoryid
) 
select p.productname, mn
from Catmin 
inner join Production.Products p
on p.categoryid = Catmin.categoryid
and p.unitprice = Catmin.mn;

第二次查询:

with Catmin as 
(
    select categoryid, MIN(unitprice) as mn
    from production.Products
    group by categoryid
) 
select p.productname, mn
from Catmin 
inner join Production.Products p
on p.categoryid = Catmin.categoryid
where p.unitprice = Catmin.mn;          // this is changed

结果两个查询:

result

3 个答案:

答案 0 :(得分:6)

我的回答可能有点偏离主题,但我想强调一下当您将INNER JOIN转换为OUTER JOIN时可能出现的问题。

在这种情况下,在ON或WHERE子句上放置谓词(测试条件)之间最重要的区别是,如果你有将LEFT或RIGHT OUTER JOINS转到INNER JOINS而不注意它将表的字段放在WHERE子句中。

例如,在表A和B之间的LEFT JOIN中,如果在WHERE子句中包含涉及B字段的条件,则很可能在结果集中不会从B返回空行。实际上,并且隐含地,您将LEFT JOIN变为INNER JOIN。

另一方面,如果在ON子句中包含相同的测试,则将继续返回空行。

例如,请执行以下查询:

SELECT * FROM A 
LEFT JOIN B
   ON A.ID=B.ID

查询还将返回A中与B中的任何一个都不匹配的行。

进行第二次查询:

SELECT * FROM A 
LEFT JOIN B
WHERE A.ID=B.ID

第二个查询不会返回A中与B不匹配的任何行,即使您认为它是因为您指定了LEFT JOIN。那是因为测试A.ID = B.ID将从结果集中排除任何B.ID为null的行。

这就是为什么我赞成将谓词放在ON子句而不是WHERE子句中。

答案 1 :(得分:5)

结果完全相同。 由于查询性能的提高,建议使用“ON”子句。

通过使用on子句,您首先过滤第一个数据集,然后将数据连接到其他表,而不是从表中请求数据然后进行过滤。因此,给出了较少的数据匹配和更快的结果。

答案 2 :(得分:3)

上述两个查询输出之间没有区别它们都相同

当您使用On Clause时,join操作仅连接那些与ON上指定的codidtion匹配的行

Where子句的情况下,join opeartion连接所有行,然后根据condidtion Specified的位置过滤掉

所以,显然On Clause更有效,应该优先于condidtion