一尘不染

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

sql

我想知道在使用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


阅读 141

收藏
2021-05-30

共1个答案

一尘不染

我的回答可能有点离题,但我想强调一下当您将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为空的行。

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

2021-05-30