【发布时间】:2021-12-28 15:54:36
【问题描述】:
我正在尝试让滚动总和在任何给定日期发生变化的类别/组金额变化 - 当发生变化时 类别的新值成为滚动总和的一部分,但之前的值然后忽略该类别的;所以这是一个滚动总和,但仅基于每个类别的最新(在那个时间点)。
示例数据(SumAmount 是试图解决的问题)
txn_id | cust_id | trans_date | Category | amount | SumAmount
-----------------------------------------------------------------
1 | 1 | 2020-01-01| Ball | 5 | 5 --first tran so sum is 5
2 | 1 | 2020-01-02| Cup | 5 | 10 --sum is 10 (ball=5,Cup=5)
3 | 1 | 2020-01-03| Ball | 2 | 7 --sum is 7 (ball=2,Cup=5)
4 | 1 | 2020-02-04| Ball | 4 | 9 --sum is 9 (ball=4,Cup=5)
5 | 1 | 2020-02-05| Ball | 1 | 6 --sum is 6 (ball=1,Cup=5)
6 | 1 | 2020-02-06| Cup | 10| 11 --sum is 11(ball=1,Cup=10)
7 | 1 | 2020-02-07| Phone | 5 | 16 --sum is 16(ball=1,Cup=10,Phone=5)
8 | 1 | 2020-02-08| Cup | 5 | 11 --sum is 11(ball=1,Cup=5,Phone=5)
9 | 1 | 2020-02-09| Ball | 5 | 15 --sum is 15(ball=5,Cup=5,Phone=5)
我已经在游标中进行了这项工作,但想知道是否可以使用基于 SET 的方法
光标如下:
CREATE PROCEDURE [dbo].[PriceHistory](@CustId int, @MaxPriceHistory decimal(16,2) Output)
create table #PriceHistory ( CategoryID uniqueidentifier, Amount decimal(16,2))
declare pricehistory_cursor CURSOR FOR
select CategoryID, Amount
from mytable
where CustId =@CustId
order by trans_date;
declare @CategoryID uniqueidentifier
declare @Amount decimal(16,2)
declare @CurrentTotal decimal(16,2)
set @MaxPriceHistory = 0
open pricehistory_cursor
fetch next from pricehistory_cursor into @CategoryID, @Amount
WHILE @@FETCH_STATUS = 0
BEGIN
if (exists(select * from #PriceHistory where CategoryID = @CategoryID))
update #PriceHistory set Amount = @actualAmount where CategoryID = @CategoryID
else
insert into #PriceHistory(CategoryID,Amount) values (@CategoryID, @Amount)
select @CurrentTotal = sum(Amount) from #PriceHistory
if (@CurrentTotal > @MaxPriceHistory)
set @MaxPriceHistory = @CurrentTotal
fetch next from pricehistory_cursor into @CategoryID, @Amount
END
close pricehistory_cursor
deallocate pricehistory_cursor;
最终,我正在寻找整个交易生命周期中的 Max SumAmount(在提供的示例中为 SumAmount 列),在本示例中为 16。
我知道光标在做什么,我知道为什么它会这样工作(如果已经存在,则替换该特定类别的金额(这是我对基于 SET 的方法感到困惑的一点,我将如何获得 Cup 金额5,当 txn_id = 5 发生时?),并将其与当时所有其他最新类别金额相加),如果可能与某种递归有关,我只是无法理解CTE 或 ROW_NUMBER。
【问题讨论】:
-
..recursion 和 json ..dbfiddle.uk/…
-
@lptr 这很时髦,以前从未使用过 JSON 函数。这是我不说明数据类型的坏处,但是 JSON 函数是否管理 MONEY 或 DECIMALS?我的金额列是钱而不是 INT
-
只是强制转换(.. 作为您的数据类型)而不是强制转换(作为 int)。
-
@lptr Ooo 看起来像 json_modify 函数不执行货币数据类型“参数数据类型货币对 json_modify 函数的参数 3 无效。”我会在谷歌周围挖掘一下! :D
-
将钱转换为 json_modify 的小数…dbfiddle.uk/…
标签: sql sql-server rolling-computation