我正在使用WorldWideImporters
Microsoft示例数据库表。我想返回的客户行中的各列将显示其2014年,2015年的总销售额,并在各自的列中分别显示两者的总和。我不允许使用任何形式的subqueries
。
对于这个问题,我正在尝试这样解决:
SELECT C.CustomerID ,C.CustomerName ,ISNULL(SUM(OL.Quantity * OL.UnitPrice), 0.00) AS [2014Sales] ,ISNULL(SUM(OLP.Quantity * OLP.UnitPrice), 0.00) AS [2015Sales] ,ISNULL(SUM(OL.Quantity * OL.UnitPrice), 0.00) + ISNULL(SUM(OLP.Quantity * OLP.UnitPrice), 0.00) AS [TotalSales] FROM Sales.Customers AS C LEFT OUTER JOIN Sales.Orders AS O ON C.CustomerID = O.CustomerID AND O.OrderDate BETWEEN '2014-01-01' AND '2014-12-31' LEFT OUTER JOIN Sales.OrderLines AS OL ON O.OrderID = OL.OrderID LEFT OUTER JOIN Sales.Orders AS OP ON O.CustomerID = C.CustomerID AND O.OrderDate BETWEEN '2015-01-01' AND '2015-12-31' LEFT OUTER JOIN Sales.OrderLines AS OLP ON OL.OrderID = O.OrderID GROUP BY C.CustomerID ,C.CustomerName ORDER BY TotalSales DESC, CustomerID;
我很难理解加入。我是从具有一些面向对象的经验而来的,我无法完全围绕关系联接工作。我可以看到如何通过子查询来解决此问题,一个子查询用于2015年,一个子查询用于2014年。
就目前而言,我的查询不断地运行,这意味着我尝试加入两次的方式必须尝试合并太多的行组合。任何帮助解释这里发生了什么以及如何解决我的查询的帮助将不胜感激。
答案 0 :(得分:1)
在编辑查询时,有些行没有意义:
您加入了相同的表,而没有在ON
语句中指出它们的条件。
请注意,您分别命名了Sales.Orders
和Sales.OrderLines
OP
和OLP
,但仍使用标准O.CustomerID = C.CustomerID
和OL.OrderID = O.OrderID
。
LEFT OUTER JOIN Sales.OrderLines AS OL ON O.OrderID = OL.OrderID LEFT OUTER JOIN Sales.Orders AS OP ON O.CustomerID = C.CustomerID AND O.OrderDate BETWEEN '2015-01-01' AND '2015-12-31' LEFT OUTER JOIN Sales.OrderLines AS OLP ON OL.OrderID = O.OrderID
看看是否可行:我刚刚更正了您的加入条件。
SELECT C.CustomerID ,C.CustomerName ,ISNULL(SUM(OL.Quantity * OL.UnitPrice), 0.00) AS [2014Sales] ,ISNULL(SUM(OLP.Quantity * OLP.UnitPrice), 0.00) AS [2015Sales] ,ISNULL(SUM(OL.Quantity * OL.UnitPrice), 0.00) + ISNULL(SUM(OLP.Quantity * OLP.UnitPrice), 0.00) AS [TotalSales] FROM Sales.Customers AS C LEFT OUTER JOIN Sales.Orders AS O ON C.CustomerID = O.CustomerID AND CONVERT(date, O.OrderDate) BETWEEN '2014-01-01' AND '2014-12-31' LEFT OUTER JOIN Sales.OrderLines AS OL ON O.OrderID = OL.OrderID LEFT OUTER JOIN Sales.Orders AS OP ON C.CustomerID = OP.CustomerID AND CONVERT(date, OP.OrderDate) BETWEEN '2015-01-01' AND '2015-12-31' LEFT OUTER JOIN Sales.OrderLines AS OLP ON OP.OrderID = OLP.OrderID GROUP BY C.CustomerID ,C.CustomerName ORDER BY [TotalSales] DESC, CustomerID;
我还向日期字段添加了CONVERT(date
,以忽略时间部分。
编辑:
如果不使用subquery
,我认为这将无效。所以我就把它留在这里,以防您已经可以使用它。
SELECT [2014].CustomerID ,[2014].CustomerName ,[2014Sales] ,[2015Sales] ,[2014Sales] + [2015Sales] AS [TotalSales] FROM ( (SELECT C.CustomerID ,C.CustomerName ,ISNULL(SUM(OL.Quantity * OL.UnitPrice), 0.00) AS [2014Sales] FROM Sales.Customers AS C LEFT OUTER JOIN Sales.Orders AS O ON C.CustomerID = O.CustomerID LEFT OUTER JOIN Sales.OrderLines AS OL ON O.OrderID = OL.OrderID WHERE O.OrderDate BETWEEN '2014-01-01' AND '2014-12-31' GROUP BY C.CustomerID ,C.CustomerName) AS [2014] LEFT OUTER JOIN (SELECT C2.CustomerID ,C2.CustomerName ,ISNULL(SUM(OLP.Quantity * OLP.UnitPrice), 0.00) AS [2015Sales] FROM Sales.Customers AS C2 LEFT OUTER JOIN Sales.Orders AS OP ON OP.CustomerID = C2.CustomerID LEFT OUTER JOIN Sales.OrderLines AS OLP ON OP.OrderID = OLP.OrderID WHERE OP.OrderDate BETWEEN '2015-01-01' AND '2015-12-31' GROUP BY C2.CustomerID ,C2.CustomerName) AS [2015] ON [2014].CustomerID = [2015].CustomerId ORDER BY [2014Sales] + [2015Sales] DESC, CustomerID;