2017-03-21 67 views
3

我發現這個: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條款。但是我一直無法讓它工作。如果涉及到它,我想我可以在它從db返回後在C#中完成它,但我寧願不必。

回答

2

使用子查詢,以確定各組grp的開始(使用lag()僅開始羣一旦當有連續的​​PaymentCC),和另一個,以產生組號sumgrp,然後使用sumgrp作爲一個分區RunningTotal

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 

rextester 演示http://rextester.com/POX67852

回報:

+-------+--------+--------------+---------+--------------+----------------+ 
| Id | UserId |  Type  | Amount | RunningTotal | desired_result | 
+-------+--------+--------------+---------+--------------+----------------+ 
| 2759 | 750 | charge  | -50.00 | -50.00  | -50.00   | 
| 2760 | 750 | charge  | -125.00 | -175.00  | -175.00  | 
| 4308 | 750 | paymentGC | 50.00 | -125.00  | -125.00  | 
| 4309 | 750 | paymentGC | 125.00 | 0.00   | 0.00   | 
| 19916 | 750 | charge  | -1.00 | -1.00  | -1.00   | 
| 19917 | 750 | creditRefund | 124.00 | 123.00  | 123.00   | 
| 23238 | 750 | paymentCC | 50.00 | 50.00  | 50.00   | 
| 23239 | 750 | paymentCC | 125.00 | 175.00  | 175.00   | 
| 23240 | 750 | charge  | -50.00 | 125.00  | 125.00   | 
| 23241 | 750 | charge  | -125.00 | 0.00   | 0.00   | 
| 41300 | 750 | creditRefund | 125.00 | 125.00  | 125.00   | 
| 42054 | 750 | paymentCC | 50.00 | 50.00  | 50.00   | 
| 42055 | 750 | paymentCC | 125.00 | 175.00  | 175.00   | 
| 42056 | 750 | charge  | -50.00 | 125.00  | 125.00   | 
| 42057 | 750 | charge  | -125.00 | 0.00   | 0.00   | 
| 56983 | 750 | creditRefund | 125.00 | 125.00  | 125.00   | 
| 63083 | 750 | paymentCC | 50.00 | 50.00  | 50.00   | 
| 63084 | 750 | paymentCC | 125.00 | 175.00  | 175.00   | 
| 63085 | 750 | charge  | -50.00 | 125.00  | 125.00   | 
| 63086 | 750 | charge  | -125.00 | 0.00   | 0.00   | 
| 80829 | 750 | creditRefund | 125.00 | 125.00  | 125.00   | 
+-------+--------+--------------+---------+--------------+----------------+ 
+0

只見參考'在我的搜索lag'但沒有明白這是什麼話,所以我甚至不能告訴它是否會使用的情況下重置幫助瞭解它。謝謝!我會試試這個。 – ahwm

+0

@ahwm樂意幫忙! – SqlZim

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 ) 
相關問題