sql - 左连接与堆叠左连接
问题描述
我想问一下这两个查询有什么区别:
SELECT
Customers.CustomerID, Customers.CustomerName, Orders.OrderID,
OrderDetails.Quantity, Products.ProductName
FROM
Customers
LEFT JOIN
(Orders
LEFT JOIN
(OrderDetails
LEFT JOIN
Products ON Products.ProductID = OrderDetails.ProductID
) ON OrderDetails.OrderID = Orders.OrderID
) ON Customers.CustomerID = Orders.CustomerID
GROUP BY
Customers.CustomerName;
VS
SELECT
Customers.CustomerID, Customers.CustomerName, Orders.OrderID,
OrderDetails.Quantity, Products.ProductName
FROM
Customers
LEFT JOIN
Orders ON Orders.CustomerID = Customers.CustomerID
LEFT JOIN
OrderDetails ON OrderDetails.OrderID = Orders.OrderID
LEFT JOIN
Products ON Products.ProductID = OrderDetails.ProductID
GROUP BY
Customers.CustomerName;
在这里测试 https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_join
从我可以看到一个选择多个条目中的第一个,一个选择多个条目中的最后一个,但这就是全部吗?
从我的角度来看,非嵌套的 LEFT Join 更容易阅读和理解。使用它有什么缺点吗?
解决方案
您的问题是错误使用GROUP BY
. 中唯一未聚合的列SELECT
应该在GROUP BY
.
这个答案的其余部分解决了关于连接的问题。
您的第二个查询被解释为:
FROM (((Customers c LEFT JOIN
Orders o
ON o.CustomerID = c.CustomerID
) LEFT JOIN
OrderDetails
ON od.OrderID = o.OrderID
) LEFT JOIN
Products p
ON p.ProductID = od.ProductID
括号会影响解释。但是有什么作用呢?本质上,你有:
(((c left join o) left join od) left join p)
相对
c left join (o left join (od left join p)))
两者都将所有记录保存在 中c
,无论第二个中的匹配如何。在这种情况下,两个版本做同样的事情。但是由于一个特殊的原因——on
条件是严格链接的(即,c 到 o,o 到 od,od 到 p)。如果p
加入 whereo
而不是od
,则可能会出现细微的差异。
有哪些细微差别?有两件事可以不同:
- 特定表中的列是否存在
NULL
或具有值。 - 由于两个表之间的多次匹配,行是否重复。
在实践中,我对细括号并不特别有用。如果可以JOIN
订购,我会使用显式子查询或 CTE>
推荐阅读
- jquery - 如何将 Watson 服务链接到 IBM Cloud 中的文件夹,我可以在 AJAX JQuery 上使用它的方式?
- javascript - 如何通过计算 Google 地球引擎中的其他图像来创建图像?
- amazon-web-services - 在 AWS 分配的负载均衡器 dns 上获取 https?
- vue.js - 没有文字的下拉菜单
- javascript - AngularJS ng-repeat with track by 渲染速度非常慢
- powershell - PowerShell脚本写出没有根目录的递归文件列表
- javascript - 我如何向后循环数组?
- c# - WPF 在代码隐藏中设置 TextBox 属性
- flutter - “Null”类型不是“图像”颤振问题的“文件”类型的子类型
- laravel - Unisharp Laravel 文件管理器,其中 /public 是 \public_html