我有一个订单表,每行都有:
我希望按日期(yyyy-mm-dd)对该期间的交易值进行分组,但我也想返回该期间的运行总额。如果我针对这几个月的数据(到11月的13天)运行此查询,那么我期望看到返回的结果集
我可以使用分组依据获取交易值分组依据日期,但没有运行总计。如果我在分区上使用 ,则每笔交易我将获得1行,但当天的交易价值之和。
当前代码如下:
SELECT
left(convert(varchar(30),OrderCheckOutDate,120),10),
SUM (OrderTotalFixed)
OVER (Partition By left(convert(varchar(30),OrderCheckOutDate,120),10))
FROM
tblOrder
Where
UserExternalUserLevel = 0
And
OrderCheckOutDate > '2019-11-01'
好像查询正在按毫秒进行分区,但我认为转换将处理此问题?
答案 0 :(得分:2)
要按日期分组,您不需要OVER (Partition By)
并将该列放在“分组依据”下
尝试一下:
;WITH TotalByDay AS (
SELECT
convert(DATE,OrderCheckOutDate) OrderCheckOutDate ,
SUM (OrderTotalFixed) OrderTotalFixed
FROM
tblOrder
Where
UserExternalUserLevel = 0
And
OrderCheckOutDate > '2019-11-01'
GROUP BY convert(DATE,OrderCheckOutDate)
)
SELECT
OrderCheckOutDate,
(SELECT SUM(TotalByDay) FROM TotalByDay innerT where innerT.OrderCheckOutDate <= T.OrderCheckOutDate) RunningTotal
FROM TotalByDay t
GROUP BY t.OrderCheckOutDate
答案 1 :(得分:2)
与其他示例相比,这里的版本缩小了代码的大小。它也应该比某些方法快一点,因为没有子查询会强制多次读取表。使用运行总计和group by语句时要记住的技巧是,您不将window函数应用于原始列,而是应用于原始列的汇总(因此我将SUM嵌套在SUM中)。
SELECT
CAST(OrderCheckOutDate AS date) AS OrderCheckOutDate,
SUM (OrderTotalFixed) AS DayTotal,
SUM (SUM (OrderTotalFixed)) OVER (ORDER BY CAST(OrderCheckOutDate AS date)) AS RunningTotal
FROM
tblOrder
Where
UserExternalUserLevel = 0
And
OrderCheckOutDate > '2019-11-01'
GROUP BY CAST(OrderCheckOutDate AS date)
您可以在dbfiddle
上看到此功能例如,如果您的实际用例更加复杂,则您希望每个月重置运行总额,可以通过将PARTITION添加到窗口函数中来处理。
按月分区将如下所示:
SELECT
CAST(OrderCheckOutDate AS date) AS OrderCheckOutDate,
EOMONTH(CAST(OrderCheckOutDate AS date)) AS MonthEnd,
SUM (OrderTotalFixed) AS DayTotal,
SUM (SUM (OrderTotalFixed)) OVER (PARTITION BY EOMONTH(CAST(OrderCheckOutDate AS date)) ORDER BY CAST(OrderCheckOutDate AS date) ) AS RunningTotal
FROM
tblOrder
Where
UserExternalUserLevel = 0
And
OrderCheckOutDate > '2019-11-01'
GROUP BY CAST(OrderCheckOutDate AS date)
再一次看到它与dbfiddle一起起作用
答案 2 :(得分:1)
这是我做过的类似事情,希望您可以根据自己的餐桌/需求进行调整。 内部查询(TOTALS_Q)仅按月获取销售和计数。 外部查询也会获取累计值。
累加的重要部分是“未绑定的行和当前行之间的行”
SELECT
SaleMonth, Month_Order_Count, MonthTotal,
SUM(Month_Order_Count) OVER(ORDER BY SaleMonth ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Cumulative_Order_Count,
SUM(MonthTotal) OVER(ORDER BY SaleMonth ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Cumulative_Order_Value
FROM
(
SELECT SUB_Q.SaleMonth, Count( DISTINCT SUB_Q.OrderID) as Month_Order_Count, SUM(Value) as MonthTotal FROM
(
SELECT CONCAT( DatePart( year, OH.OrderDate), '-', FORMAT( OH.OrderDate, 'MM')) as SaleMonth,
OI.OrderID,
OI.Value
FROM ORDERHEADER OH
INNER JOIN OrderItem OI ON OI.OrderID = OH.OrderID
INNER JOIN ECodeOrder ECO ON ECO.OrderId = OH.ORDERID
INNER JOIN Product P ON P.ProductId = OI.ProductId AND P.Denomination >= 10000
) SUB_Q
GROUP BY SUB_Q.SaleMonth
)TOTALS_Q
ORDER BY SaleMonth