2015-06-19 101 views
-2

我想根據某些條件獲取累計總計。以下是一個虛擬樣本數據集。我想獲得基於Indicator以及ID的累計時間。當Indicator連續1爲相同的ID,我想得到的所有Duration的總和。如果它變成0那麼我想重新啓動。基於條件的累計總計

ID Duration Indicator Cumm_duration 
1 30   0   30 
1 30   1   60 
1 30   0   30 
1 30   0   30 
1 30   1   60 
1 30   0   30 
1 30   0   30 
1 30   0   30 
1 30   0   30 
1 30   0   30 
1 30   0   30 
1 30   0   30 
1 30   1   60 
1 30   1   90 
2 30   1   30 
2 30   0   30 
2 30   0   30 
2 30   0   30 
2 30   1   60 
2 30   0   30 
2 30   1   60 
2 30   0   30 
2 30   0   30 
2 30   0   30 
2 30   1   60 
2 30   1   90 
2 30   0   30 
+1

1.如果你格式化你的樣品作爲這會更容易帶有插入數據的表格。 2.沒有表示記錄順序的列,因此查詢無法知道處理指示符的順序。 –

+0

爲了獲得一致的結果,您必須有一個可以按順序排列的列。 –

回答

0

數據:

DECLARE @t TABLE 
    (
     ID INT , 
     Duration INT , 
     INDICATOR INT 
    ) 
INSERT INTO @t 
VALUES (1, 30, 0), 
     (1, 30, 1), 
     (1, 30, 0), 
     (1, 30, 0), 
     (1, 30, 1), 
     (1, 30, 0), 
     (1, 30, 0), 
     (1, 30, 0), 
     (1, 30, 0), 
     (1, 30, 0), 
     (1, 30, 0), 
     (1, 30, 0), 
     (1, 30, 1), 
     (1, 30, 1), 
     (2, 30, 1), 
     (2, 30, 0), 
     (2, 30, 0), 
     (2, 30, 0), 
     (2, 30, 1), 
     (2, 30, 0), 
     (2, 30, 1), 
     (2, 30, 0), 
     (2, 30, 0), 
     (2, 30, 0), 
     (2, 30, 1), 
     (2, 30, 1), 
     (2, 30, 0); 

解決方法1(暴力破解):

with indexed 
      as (select * , 
         row_number() over (order by (select null)) rn 
       from  @t 
      ), 
     recursion 
      as (select * , 
         duration as cumulative 
       from  indexed 
       where rn = 1 
       union all 
       select t.* , 
         case when t.indicator = 1 and t.id = r.id 
          then r.cumulative + t.duration 
          else t.duration 
         end 
       from  indexed t 
         join recursion r on r.rn + 1 = t.rn 
      ) 
    select * from recursion 
    option (maxrecursion 0) 

溶液2:

with indexed as (select *, row_number() over (order by (select null)) rn from @t) 
select *, 
     (select sum(duration) from indexed i2 
     where i1.id = i2.id and i2.rn <= i1.rn and 
       i2.rn >= isnull((select top 1 i3.rn from indexed i3 
           where i3.indicator = 0 and i3.rn <= i1.rn 
           order by i3.rn desc), 0)) 
from indexed i1