我的代码是否可以解决以下问题? 1996年7月订购的所有订单的总成本。查看2个表(Orders
和OrderDetails
)这是我到目前为止所做的。
SELECT
Orders.OrderID, Customers.ContactName, Orders.OrderDate
FROM
Customers
INNER JOIN
Orders ON Customers.CustomerID = Orders.CustomerID
INNER JOIN
[Order Details] ON Orders.OrderID = [Order Details].OrderID
WHERE
(Orders.OrderDate BETWEEN CONVERT(DATETIME, '1996-07-01 00:00:00', 102) AND CONVERT(DATETIME, '1996-07-31 00:00:00', 102))
AND SUM(Quantity * UnitPrice) AS grand_total;
目的是找到每一行的总和并保留该数字,然后对行进行求和以产生总计。当我运行查询时,它肯定不会产生应该是什么。
答案 0 :(得分:2)
试试这个:
SELECT
o.OrderID, c.ContactName, o.OrderDate, SUM(od.Quantity * od.UnitPrice) AS grand_total
FROM
dbo.Customers c
INNER JOIN
dbo.Orders o ON c.CustomerID = o.CustomerID
INNER JOIN
dbo.[Order Details] od ON o.OrderID = od.OrderID
WHERE
o.OrderDate BETWEEN {ts '1996-07-01 00:00:00.000'} AND {ts '1996-07-31 23:59:59.997'}
GROUP BY
GROUPING SETS ((o.OrderID, c.ContactName, o.OrderDate), ())
GROUPING SETS ((o.OrderID, c.ContactName, o.OrderDate), ...)
会按o.OrderID, c.ContactName, o.OrderDate
对源行进行分组,并且还会计算每SUM
个值对的OrderID, ContactName, OrderDate
。
GROUPING SETS ((...), ())
指示SQL Server计算总计(所有订单总计的总和):
SELECT OrderID, SUM(OrderDetailValue) AS OrderTotal
FROM (
SELECT 11, 1, 'A', 1 UNION ALL
SELECT 12, 1, 'B', 10 UNION ALL
SELECT 13, 2, 'A', 100
) AS Orders(OrderDetailID, OrderID, ProductName, OrderDetailValue)
GROUP BY GROUPING SETS ((OrderID), ());
结果:
OrderID OrderTotal
------- ----------
1 11 <-- Total generated by GROUPING SETS ((OrderID), ...)
2 100 <-- Total generated by GROUPING SETS ((OrderID), ...)
NULL 111 <-- Total generated by GROUPING SETS (..., ())
答案 1 :(得分:1)
有很多方法可以做到这一点。
GROUP BY ROLLUP - http://technet.microsoft.com/en-us/library/ms177673.aspx
分组集 - http://technet.microsoft.com/en-us/library/bb522495(v=SQL.105).aspx
OVER - http://technet.microsoft.com/en-us/library/ms189461.aspx
不要使用Shiva的解决方案,因为COMPUTE在SQL Server 2012中已经不存在了!
以下是我在解决方案中纠正的一些问题。
1 - Use table alias's
2 - Do not use between or convert on date ranges.
It will not be SARGABLE.
由于您并非具体,因此无论订单ID如何,我都会根据客户订单ID选择一个简单的总和,其中包含客户的总月份。
为了解决这个问题,我使用了OVER子句。由于我没有您的测试数据或表格,因此检查解决方案是否存在语法错误是您的作业。
-- Customer sum by order id, total sum by customer.
SELECT
C.ContactName,
O.OrderID,
O.OrderDate,
SUM(D.Quantity * D.UnitPrice) AS OrderTotal,
SUM(D.Quantity * D.UnitPrice) OVER (PARTITION BY C.ContactName) as CustomerTotal
FROM Customers as c INNER JOIN Orders as O
ON C.CustomerID = O.CustomerID
INNER JOIN [Order Details] D
ON O.OrderID = D.OrderID
WHERE
O.OrderDate >= '1996-07-01 00:00:00' AND
O.OrderDate < '1996-08-01 00:00:00'
GROUP BY
C.ContactName,
O.OrderID,
O.OrderDate
答案 2 :(得分:0)
;WITH CTE
AS(
SELECT Orders.OrderID
, Customers.ContactName
, Orders.OrderDate
, SUM(Quantity * UnitPrice) AS grand_total
, rn = ROW_NUMBER() OVER (ORDER BY Orders.OrderID)
FROM Customers INNER JOIN
Orders ON Customers.CustomerID = Orders.CustomerID INNER JOIN
[Order Details] ON Orders.OrderID = [Order Details].OrderID
WHERE MONTH(Orders.OrderDate) = 7 AND YEAR(Orders.OrderDate) = 1996
GROUP BY Orders.OrderID
, Customers.ContactName
, Orders.OrderDate
)
SELECT A.OrderID
, A.ContactName
, A.OrderDate
, A.grand_total
, (SELECT SUM(grand_total)
FROM CTE B
WHERE B.grand_total > A.grand_total) RunningTotal
FROM CTE A
ORDER BY RunningTotal
结果集
╔═════════╦═════════════════════╦═════════════════════════╦═════════════╦══════════════╗
║ OrderID ║ ContactName ║ OrderDate ║ grand_total ║ RunningTotal ║
╠═════════╬═════════════════════╬═════════════════════════╬═════════════╬══════════════╣
║ 10267 ║ Peter Franken ║ 1996-07-29 00:00:00.000 ║ 4031.00 ║ NULL ║
║ 10252 ║ Pascale Cartrain ║ 1996-07-09 00:00:00.000 ║ 3730.00 ║ 4031.00 ║
║ 10255 ║ Michael Holz ║ 1996-07-12 00:00:00.000 ║ 2490.50 ║ 7761.00 ║
║ 10263 ║ Roland Mendel ║ 1996-07-23 00:00:00.000 ║ 2464.80 ║ 10251.50 ║
║ 10258 ║ Roland Mendel ║ 1996-07-17 00:00:00.000 ║ 2018.60 ║ 12716.30 ║
║ 10249 ║ Karin Josephs ║ 1996-07-05 00:00:00.000 ║ 1863.40 ║ 14734.90 ║
║ 10250 ║ Mario Pontes ║ 1996-07-08 00:00:00.000 ║ 1813.00 ║ 16598.30 ║
║ 10260 ║ Henriette Pfalzheim ║ 1996-07-19 00:00:00.000 ║ 1746.20 ║ 18411.30 ║
║ 10253 ║ Mario Pontes ║ 1996-07-10 00:00:00.000 ║ 1444.80 ║ 20157.50 ║
║ 10265 ║ Frédérique Citeaux ║ 1996-07-25 00:00:00.000 ║ 1176.00 ║ 21602.30 ║
║ 10257 ║ Carlos Hernández ║ 1996-07-16 00:00:00.000 ║ 1119.90 ║ 22778.30 ║
║ 10268 ║ Manuel Pereira ║ 1996-07-30 00:00:00.000 ║ 1101.20 ║ 23898.20 ║
║ 10264 ║ Maria Larsson ║ 1996-07-24 00:00:00.000 ║ 724.50 ║ 24999.40 ║
╚═════════╩═════════════════════╩═════════════════════════╩═════════════╩══════════════╝