【问题标题】:What's the difference between filtering in the WHERE clause compared to the ON clause?与 ON 子句相比,WHERE 子句中的过滤有什么区别?
【发布时间】:2013-10-03 08:21:42
【问题描述】:

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

结果两个查询:

【问题讨论】:

  • 在这种情况下,两者的结果与您从 2 个表进行比较的结果相同。第一个将只选择符合条件的那些进行绑定,第二个将绑定两个表并过滤掉条件。
  • 在 SSMS 工具栏上寻找一个按钮,工具提示显示“包括实际执行计划” - 单击它,然后运行两个查询并进行比较。

标签: sql tsql sql-server-2012


【解决方案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 子句中的原因。

【讨论】:

  • 我在这里学到的最重要的一点是 ON 子句在 where 子句之前执行,这就是结果在连接之后被过滤的原因。感谢您的回答!
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    以上两个查询输出没有区别两者结果相同

    当您使用 On Clause 时,连接操作仅连接那些与 ON Clause 中指定的代码匹配的行

    Where 子句的情况下,连接操作会连接所有行,然后根据指定的条件过滤掉

    所以,显然 On 子句更有效,应该优先于 where 条件

    【讨论】:

      猜你喜欢
      • 2012-01-08
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      相关资源
      最近更新 更多