我通常非常精通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,Transaction.Date FROM Product INNER JOIN ( Transaction INNER JOIN Customer ON Transaction.CustomerID = Customer.ID) ON Transaction.ProductID = Product.ID
这是什么?只是另一种语法或性能技巧?
(这是在sqlServer,FYI,但可能是可以应用于其他人……)
解决方法
括号不会改变语义. ON子句的位置控制连接的逻辑处理顺序.
第一次查询
SELECT Customer.Name,Transaction.Date FROM Product INNER JOIN Transaction ON Transaction.ProductID = Product.ID INNER JOIN Customer ON Transaction.CustomerID = Customer.ID
第二个查询
(删除了冗余括号)
SELECT Customer.Name,Transaction.Date FROM Product INNER JOIN Transaction INNER JOIN Customer ON Transaction.CustomerID = Customer.ID ON Transaction.ProductID = Product.ID
所以逻辑上在你的第一个例子中,事务上的连接,产品首先发生,然后由此产生的虚拟表连接到客户,而在第二个示例中,客户首先发生,然后由此产生的虚拟表连接到产品
这只是逻辑上的,因为内部联接既是关联的又是可交换的,这可能不会对执行计划产生任何影响(除非您向查询添加OPTION(FORCE ORDER)),但它可以用于外部联接.
这是covered by Itzik Ben Gan here,但文章有许多不准确之处,请参阅follow up letter by Lubor Kollar.