9

如果我有这样的查询:

SELECT
    A.ID,
    A.Name,
    A.Type,
    B.FirstName,
    B.LastName,
    B.DateOfBirth,
    C.OfficeName
FROM A
    INNER JOIN B ON A.ContactID = B.ID
    INNER JOIN C ON B.OfficeID = C.ID
WHERE
    A.Type = 1

何时应用 A.Type = 1 过滤器?是在连接之后,还是查询查找“A”,确定它是否通过过滤器,如果通过,则只连接到 B 和 C?

希望这是有道理的。谢谢。

4

5 回答 5

13

首先,以下是 SQL 操作顺序:

  • FROM 子句
  • WHERE 子句
  • GROUP BY 子句
  • HAVING 子句
  • 选择子句
  • ORDER BY 子句

在一个简单的查询中,过滤发生在FROM子句之后(在这部分找到连接)。您上面的查询所做的是主要将表与定义它们关系的链接列连接起来。设置记录后(连接的结果),WHERE然后执行子句以过滤掉Typeis 等于 1 的位置。


这是另一个使用的例子LEFT JOIN

第一个查询:

SELECT  A.ID,
        A.Name,
        A.Type,
        B.FirstName,
        B.LastName,
        B.DateOfBirth
FROM    A
        LEFT JOIN B 
            ON  A.ContactID = B.ID AND
                B.LastName = 'Michaels'

与第二个查询:

SELECT  A.ID,
        A.Name,
        A.Type,
        B.FirstName,
        B.LastName,
        B.DateOfBirth
FROM    A
        LEFT JOIN B ON  A.ContactID = B.ID
WHERE   B.LastName = 'Michaels'

第一个查询返回 table 中的所有记录A。什么B.LastName = 'Michaels'是在表B将与表连接之前A,它会过滤掉所有LastName等于的记录Michaels。因此,A在 Table 上的过滤记录上没有匹配的 table 中的记录将在 Table的列上B具有NULLB值。

第二个查询将不会产生与第一个查询相同的结果,并且执行完全相同的结果,INNER JOIN因为在连接记录后,将对结果执行另一个过滤,并且只获取LastName等于Michaels的记录。

于 2013-03-04T16:11:09.733 回答
6

逻辑上——在joins 之后,物理上——取决于优化器。

于 2013-03-04T16:03:24.963 回答
4

根据MSDN
检查标题为 SELECT 语句的逻辑处理顺序的部分

  1. 加入
  2. 在哪里
  3. 通过...分组
  4. WITH CUBE 或 WITH ROLLUP
  5. 拥有
  6. 选择
  7. 清楚的
  8. 订购方式
  9. 最佳

在此列表之前的段落末尾有一个重要说明。

请注意,语句的实际物理执行由查询处理器确定,并且顺序可能与此列表不同。

于 2013-03-04T16:10:22.367 回答
2

要回答这个问题,您确实需要查看执行计划。在您提到的情况下,在 where 子句中有可搜索参数(SARG)的情况下,过滤器很可能会在连接之前与您的访问方法一起应用,即索引、表扫描等。

采用

查询菜单 -> 包括实际执行计划

或者

查询菜单 -> 显示预计执行计划

去看一眼。

于 2013-03-04T16:06:54.687 回答
1

Where 子句将在连接之前应用,即它将返回 A 的所有行以及 B 和 C 中的相应行取决于连接条件和类型 = 1

于 2013-03-04T16:12:14.910 回答