sql - 奇数 INNER JOIN 语法和封装

标签 sql sql-server inner-join

我通常非常熟悉 JOINS,但这是新的。

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

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

(Simplistic on purpose, I can't reproduce the actual structure, it's not my code.)

Normally, to get a table of "who bought what when", I'd do this:

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 上,仅供引用,但大概可以应用于其他人......)

最佳答案

括号不会改变语义。 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) 添加到查询中),但它可以用于外连接。

这是 covered by Itzik Ben Gan here但文章有不少不准确之处,见follow up letter by Lubor Kollar以及。

关于sql - 奇数 INNER JOIN 语法和封装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33964177/

相关文章:

mysql - 用于根据特定条件计算记录并返回计数的 SQL 脚本

mysql - 从一个表中选择在另一个表中多次出现的元素

c# - SQL Real 和 .NET double 之间的转换

mysql - 独家mysql select查询,两张表

php - 如何检查数组中的哪些值在 MySQL 中?

sql-server - Transact SQL 如何在毕业变化(促销)时标记 person_id

mysql - 需要有返回所有数据的 sql 查询,除了只有零的数据

java - 在 Java App 中删除 If Exists 查询

mysql - 内连接语句限制在三个表之一

mysql - SQL查询从内部连接返回多个数据