一尘不染

奇怪的INNER JOIN语法和封装

sql

我通常对JOINS十分熟悉,但这是新的。

假设三个表(两个表的典型情况和第三个链接器表):

Customer  Product  Transaction
--------  -------  -----------
ID        ID       CustomerID
Name      Desc     ProductID
          Cost     Date

(出于简化目的,我无法复制实际的结构,这不是我的代码。)

通常,要获得“谁在什么时候买了什么”的表格,我可以这样做:

SELECT Customer.Name, Product.Desc, Transaction.Date
FROM Product
INNER JOIN Transaction ON Transaction.ProductID = Product.ID
INNER JOIN Customer ON Transaction.CustomerID = Customer.ID

但是我已经看到了这个:

SELECT Customer.Name, Product.Desc, Transaction.Date
FROM Product
INNER JOIN ( Transaction
      INNER JOIN Customer ON Transaction.CustomerID = Customer.ID)
ON Transaction.ProductID = Product.ID

这是什么?只是另一种语法,还是一种性能技巧?

(它在SQLServer,FYI上,但是大概可以应用于其他…)


阅读 180

收藏
2021-05-05

共1个答案

一尘不染

括号不会改变语义。ON子句的位置控制联接的逻辑处理顺序。

第一次查询

SELECT Customer.Name,
       Product.Desc,
       Transaction.Date
FROM   Product
       INNER JOIN Transaction
         ON Transaction.ProductID = Product.ID
       INNER JOIN Customer
         ON Transaction.CustomerID = Customer.ID

第二查询

(多余的括号已删除)

SELECT Customer.Name,
       Product.Desc,
       Transaction.Date
FROM   Product
       INNER JOIN Transaction
                  INNER JOIN Customer
                    ON Transaction.CustomerID = Customer.ID
         ON Transaction.ProductID = Product.ID

因此, 从逻辑上讲, 在您的第一个示例中,连接Transaction, Product首先发生,然后将由此产生的虚拟表连接到Customer,而在您的第二个示例中,Transaction, Customer首先发生连接,然后将由此产生的虚拟表连接到Product

这仅是逻辑上的,并且由于内部联接既具有关联性又具有可交换性,因此这对执行计划可能没有任何影响(除非您添加OPTION (FORCE ORDER)到查询中),但对于外部联接则可以。

2021-05-05