我发现了这个:How to group/rank records based on a changing value of a column?这与我正在寻找的相似,但并不像我需要的那样工作。
基本上,我的数据看起来像这样:
Id UserId Type Amount RunningTotal
----------- ----------- --------------- -------- -------------
2759 750 charge -50.00 -50.00
2760 750 charge -125.00 -175.00
4308 750 paymentGC 50.00 -125.00
4309 750 paymentGC 125.00 0.00
19916 750 charge -1.00 -1.00
19917 750 creditRefund 124.00 123.00
23238 750 paymentCC 50.00 173.00
23239 750 paymentCC 125.00 298.00
23240 750 charge -50.00 248.00
23241 750 charge -125.00 123.00
41300 750 creditRefund 125.00 248.00
42054 750 paymentCC 50.00 298.00
42055 750 paymentCC 125.00 423.00
42056 750 charge -50.00 373.00
42057 750 charge -125.00 248.00
56983 750 creditRefund 125.00 373.00
63083 750 paymentCC 50.00 423.00
63084 750 paymentCC 125.00 548.00
63085 750 charge -50.00 498.00
63086 750 charge -125.00 373.00
80829 750 creditRefund 125.00 498.00
这很有效,但每次遇到RunningTotal
时我都需要重置creditRefund
。我查看了使用OVER(ROWS BETWEEN CURRENT ROW AND x FOLLOWING)
,但这不起作用,因为它们之间可以有任意数量的行,具体取决于帐户上发生的情况。
所以我需要它看起来更像这样:
Id UserId Type Amount RunningTotal
----------- ----------- --------------- -------- -------------
2759 750 charge -50.00 -50.00
2760 750 charge -125.00 -175.00
4308 750 paymentGC 50.00 -125.00
4309 750 paymentGC 125.00 0.00
19916 750 charge -1.00 -1.00
19917 750 creditRefund 124.00 123.00
23238 750 paymentCC 50.00 50.00
23239 750 paymentCC 125.00 175.00
23240 750 charge -50.00 125.00
23241 750 charge -125.00 0.00
41300 750 creditRefund 125.00 125.00
42054 750 paymentCC 50.00 50.00
42055 750 paymentCC 125.00 175.00
42056 750 charge -50.00 125.00
42057 750 charge -125.00 0.00
56983 750 creditRefund 125.00 125.00
63083 750 paymentCC 50.00 50.00
63084 750 paymentCC 125.00 175.00
63085 750 charge -50.00 125.00
63086 750 charge -125.00 0.00
80829 750 creditRefund 125.00 125.00
这是我到目前为止所得到的:
SELECT Id, UserId, [Type], RunningTotal = SUM(Amount) OVER (ORDER BY t.Id)
FROM Transactions
WHERE UserId = @User
关于如何实现这一目标的任何想法?我觉得我需要以某种方式对它们进行分组,以便运行总重置并且我可以使用PARTITION BY
子句。但是我无法让它发挥作用。如果它归结为它,我想我可以在从C#返回之后在C#中完成它,但我宁愿不必这样做。
答案 0 :(得分:2)
使用子查询来标识每个组的开始grp
(使用lag()
仅在有顺序PaymentCC
时启动组一次,而另一个用于生成组编号{ {1}},然后使用sumgrp
作为sumgrp
的分区:
RunningTotal
rextester 演示:http://rextester.com/POX67852
返回:
select
Id
, UserId
, Type
, Amount
, RunningTotal = sum(amount) over (partition by userid, sumgrp order by id)
, desired_result
from (
select *
, sumgrp = sum(grp) over (
partition by userid
order by id
)
from (
select *
, grp = (case when type='PaymentCC'
and isnull(lag(type) over (
partition by userid
order by id
),'') <> 'PaymentCC'
then 1
else 0 end)
from Transactions
) as g
) as s
where UserId = 750
答案 1 :(得分:0)
您可以使用总计
中的大小写重置;with cte as (
select *, sum(amount) over(order by id) RowSum, case when [Type]='creditRefund' Then 1 else 0 end as Num from #yourtable
)
, cte2 as ( SELECT *, sum(num) over (order by id) ResetFlag from cte )
select *, sum(case when [Type]='creditRefund' Then 0 else Amount END) over(partition by ResetFlag order by id) from cte2
create table #yourtable ( id int, userid int, type varchar(20), amount float)
insert into #yourtable (
Id , UserId , Type , Amount ) values
----------- ----------- --------------- -------- -------------
(2759 , 750 , 'charge ', -50.00 )
,(2760 , 750 , 'charge ', -125.00 )
,(4308 , 750 , 'paymentGC ', 50.00 )
,(4309 , 750 , 'paymentGC ', 125.00 )
,(19916 , 750 , 'charge ', -1.00 )
,(19917 , 750 , 'creditRefund', 124.00 )
,(23238 , 750 , 'paymentCC ', 50.00 )
,(23239 , 750 , 'paymentCC ', 125.00 )
,(23240 , 750 , 'charge ', -50.00 )
,(23241 , 750 , 'charge ', -125.00 )
,(41300 , 750 , 'creditRefund', 125.00 )
,(42054 , 750 , 'paymentCC ', 50.00 )
,(42055 , 750 , 'paymentCC ', 125.00 )
,(42056 , 750 , 'charge ', -50.00 )
,(42057 , 750 , 'charge ', -125.00 )
,(56983 , 750 , 'creditRefund', 125.00 )
,(63083 , 750 , 'paymentCC ', 50.00 )
,(63084 , 750 , 'paymentCC ', 125.00 )
,(63085 , 750 , 'charge ', -50.00 )
,(63086 , 750 , 'charge ', -125.00 )
,(80829 , 750 , 'creditRefund', 125.00 )