【问题标题】:How SQL Server Engine work for this join scenario? [duplicate]SQL Server 引擎如何在此联接方案中工作? [复制]
【发布时间】:2021-10-21 03:22:26
【问题描述】:

我使用的是 SQL Server 2019,在优化时我发现加入条件的放置方式不同,如下所示,

SELECT * 
FROM #table1 a 
INNER JOIN dbo.table2 b 
INNER JOIN dbo.table3 c ON c.id = b.id 
                        ON b.id=a.id

SQL Server 引擎实际上是如何工作的? 把这个join改成如下后,sql server会返回类似的返回,

   SELECT * 
    FROM #table1 a 
    INNER JOIN dbo.table2 b ON b.id=a.id
    INNER JOIN dbo.table3 c ON c.id = b.id 
                            

能否请您帮助我了解这两个查询的工作方式是否相同?如果不是,那么第一个查询与第二个查询有何不同?

【问题讨论】:

  • #table1 和 table2 之间的第一个查询执行 CROSS JOIN,#table1 的每一行与 table2 的每一行连接。 See this
  • @Max - 不,它没有。它完全按照它所说的那样执行INNER JOIN。不同之处在于该连接是在 另一个连接之后计算的。
  • 在这种情况下,只有INNER JOIN和每个ON子句只引用两个表,逻辑结果是相同的。
  • 通常,当第一个连接是LEFT JOIN 时,前一种语法更有意义;仅INNER JOINs 确实不需要令人困惑的语法。
  • @Damien_The_Unbeliever 你是对的,我读得很快我没有注意到第二个b.id = a.id。对不起。

标签: sql-server


【解决方案1】:

在这种情况下,从逻辑上讲,查询是等效的。

首先,使用ON c.id = b.id 计算bc 之间的连接(逻辑上)。请注意,a 不在此 ON 子句的范围内。让我们将结果称为bc

然后abc 之间的连接是使用 ON b.id=a.id1 计算的。请注意,第二个ON 子句可能也引用了c

ON 子句的位置改变了计算JOINs 的顺序,这对INNER JOINs 没有影响。

第二个查询更容易阅读,因为每个JOIN 都以它们的计算顺序出现。

如果第一个连接是 LEFT JOIN,那么由于连接顺序不同,您可能会开始看到两个查询之间的差异。


1这里我经常使用括号的类比——要找到JOINs 的计算顺序,你需要找到它们对应的ON 子句。如果您将每个JOIN 视为( 并将每个ON 视为),则匹配的括号表示哪个JOINON 子句匹配。

【讨论】:

    猜你喜欢
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 2018-02-07
    • 2013-09-03
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    相关资源
    最近更新 更多