【发布时间】:2018-09-17 22:56:52
【问题描述】:
问题陈述:
编写查询以返回每个供应商的 2015 年销售信息。我们希望将所有供应商都包括在结果集中,无论他们的产品是否在 2015 年售出。
与前两个问题一样,使用 Sales.Orders 和 Sales.OrderLines 确定销售额。但是,由于我们是从供应商的角度询问此信息,因此您还需要使用表 Warehouse.StockItems 和 Purchasing.Suppliers。
结果集中需要的列是:
SupplierID - 出现在 Purchasing.Suppliers 表中。
SupplierName - 出现在 Purchasing.Suppliers 表中。
OrderCount - 每个供应商的产品订单数量。
Sales - 已下订单的小计,根据 Sales.OrderLines 表的 Quantity 和 UnitPrice 计算。应对结果进行排序,以使销售额最高的供应商位于顶部。如果两个供应商的销售额相同,则接下来使用顶部计数最高的订单计数。如果两个供应商的销售额和订单数相同,则使用供应商名称升序排列作为最后的决胜局。这将确保一个确定性的结果。
我正在使用WorldWideImporters Microsoft 示例数据库表。我正在尝试为Purchasing.Suppliers 中的每个供应商返回2015 sales information。我在各自的列中返回OrderCount 和Sum of the 2015 sales。我在这里遇到了joins 的问题,因为我必须将Suppliers 连接到Warehouse.StockItems,然后将这些项目连接到具有StockItemID 字段的特定OrderLines。
问题是我通常会加入orders 到orderlines,这样我就可以只过滤orders 和orderlines 中的2015。但是,使用我指定的表结构,似乎我必须将OrderLines 连接到Orders。
所以我所做的就是将join 那些Orders 与OrderLines 一起返回以提供我习惯的结果。这是我的解决方案尝试:
<pre>
SELECT S.SupplierID
,S.SupplierName
,COUNT(DISTINCT O.OrderID) AS OrderCount
,ISNULL(SUM(OLP.Quantity * OLP.UnitPrice), 0.00) AS Sales
FROM Purchasing.Suppliers AS S
LEFT OUTER JOIN Warehouse.StockItems AS W ON S.SupplierID = W.SupplierID
LEFT OUTER JOIN Sales.OrderLines AS OL ON W.StockItemID = OL.StockItemID
LEFT OUTER JOIN Sales.Orders AS O ON OL.OrderID = O.OrderID
AND O.OrderDate BETWEEN '2015-01-01' AND '2015-12-31'
LEFT OUTER JOIN Sales.OrderLines AS OLP ON O.OrderID = OLP.OrderID
GROUP BY S.SupplierID
,S.SupplierName
ORDER BY Sales DESC
,OrderCount
,SupplierName;
</pre>
编辑:
结果:
期待每个supplier 都符合预期,即使没有sales 或orders。我不确定计算出的sales 是否正确,我不确定如何验证。不知道有没有人发现我的查询有问题。
我不知道这是否正确或解决此问题的最有效方法。我确实有一些限制,我只能使用joins,不能使用subqueries、unions 等。
任何有助于理解的帮助将不胜感激。谢谢。
【问题讨论】:
-
你应该用源表标记每一列。
-
请阅读minimal reproducible example并采取行动。表明您的程序在通过(子)表达式时计算出您期望的结果——包括传递给每个函数/运算符的参数是否满足其要求——通过说明这是什么并表明它实际上是通过增量输出完成的。找到 MCVE 的一部分是找到部分功能的最大工作示例。询问示例之间的(小)差异。请阅读并按照谷歌搜索“stackexhange 作业”的点击量采取行动。 PS“将订单连接到订单行”与“将订单行连接到订单”有何不同?
-
请在您的问题中添加您正在使用的链接。但也请让您的帖子独立,包括 DDL、示例输入和所需输出等。链接死了。 PS您不清楚重新匹配的行如何影响结果。我们无法从您的查询中推断出,因为您没有说它是正确的。当然,我们可以猜测。但能够清楚地表达这一点是解决方案编程的一部分并给出minimal reproducible example。另外,what does "efficient" mean? 另见Why is “Can someone help me?” not an actual question?。
-
嗨。了解 LEFT JOIN 返回的内容:INNER JOIN 行加上由 NULL 扩展的不匹配的左表行。作为 LEFT JOIN 的一部分,始终知道您想要什么 INNER JOIN。在您拥有的 LEFT JOIN 之后,需要右表列不为 NULL 的 WHERE 或 ON 删除任何由 NULL 扩展的行,即只留下 INNER JOIN 行,即“将 LEFT JOIN 转换为 INNER JOIN”。
-
@philipxy 我已经更新了我的问题。我对这两个 SQL 和这个论坛都是新手,所以请给我反馈。谢谢
标签: sql-server tsql join