Sql server SQL server:如何计算中每个观察值的最大持续更改

Sql server SQL server:如何计算中每个观察值的最大持续更改,sql-server,cursor,window,fetch,aggregate-functions,Sql Server,Cursor,Window,Fetch,Aggregate Functions,我用的是SQLServer2012。我想计算每个obs的最大连续更改数。像这样的桌子 snapshot\u date customer\u id Number Max\u consercutive\u increase\u作为每行的\u 一月十四日1234200 二月十四日12342 15 1 三月十四日12342452 四月十四日12342 02 5月14日12342 15 2 六月十四日12342452 七月十四日12342753 八月十四日12342 105 4 2014年9月12342

我用的是SQLServer2012。我想计算每个obs的最大连续更改数。像这样的桌子

snapshot\u date customer\u id Number Max\u consercutive\u increase\u作为每行的\u
一月十四日1234200
二月十四日12342 15 1
三月十四日12342452
四月十四日12342 02
5月14日12342 15 2
六月十四日12342452
七月十四日12342753
八月十四日12342 105 4
2014年9月12342 135 5
10月14日12342 04
11月14日12342 03
十二月十四日12342 02
一月十五日12342 01
二月十五日1234200
三月十五日1234200

4月15日12342 0 0
这应该适合您:

-- Create test data

declare @t table(snapshot_date date,customer_id int,Number int);
insert into @t values ('20140101',12342,    0   ),('20140201',12342,    15  ),('20140301',12342,    45  ),('20140401',12342,    0   ),('20140501',12342,    15  ),('20140601',12342,    45  ),('20140701',12342,    75  ),('20140801',12342,    105 ),('20140901',12342,    135 ),('20141001',12342,    0   ),('20141101',12342,    0   ),('20141201',12342,    0   ),('20150101',12342,    0   ),('20150201',12342,    0   ),('20150301',12342,    0   ),('20150401',12342,    0   );

with d as    -- Add a row number to the dataset
(
    select snapshot_date
            ,customer_id
            ,Number
            ,row_number() over (order by snapshot_date) as rn
    from @t
)
,c as        -- Use a recursive CTE to loop through the dataset and check for increases
(
    select snapshot_date
            ,customer_id
            ,Number
            ,rn
            ,0 as ConsecutiveIncreases
    from d
    where rn = 1

    union all

    select t.snapshot_date
            ,t.customer_id
            ,t.Number
            ,t.rn
            ,case when t.Number > c.Number then c.ConsecutiveIncreases + 1 else 0 end
    from d as t
        join c
            on t.rn = c.rn+1
)
-- Take the MAX consecutive increase where the current row is also an increase,
-- unless the row is not an increase, then subtract the number of non-increases
-- from the MAX consecutive increase to find the number of increases within the last 6 rows.
-- If less than 6 rows to use, just take the MAX increase.
select c.snapshot_date
        ,c.customer_id
        ,c.Number
        ,case when isnull(sum(c2.ConsecutiveIncreases),0) = 0
                then 0
              when count(c2.ConsecutiveIncreases) < 6
                then max(c2.ConsecutiveIncreases)
              else max(c2.ConsecutiveIncreases) - case when c.ConsecutiveIncreases = 0
                                                       then sum(case when c2.ConsecutiveIncreases = 0
                                                                     then 1
                                                                     else 0
                                                                     end
                                                               )
                                                       else 0
                                                       end
          end as MaxConsecutiveIncreases
from c
    left join c as c2
        on c2.rn between c.rn-5 and c.rn
group by c.snapshot_date
        ,c.customer_id
        ,c.Number
        ,c.ConsecutiveIncreases
order by 1

你能把你的脚本发布到现在吗?你是怎么尝试的。我曾经尝试过使用游标和fetch-relative,比如:fetch-relative-5 from Test1cursor to。。。从Test1cursor获取相对-5到。。。谢谢你的回答。但我认为在快照日期2014-04-01,MaxConcertiveIncrease应该是2,因为前面06行中的“number”列增加了02倍。请分享更多关于你的逻辑,因为这对我来说是新的,还有一件事@iamdave。我的表大约有1.000.000行,因此如果我使用递归cte,会出现问题,因为临时数据非常大?@trato更新了我的脚本。由于您希望这样做,我还无法找到一种有效的基于集合的方式来实现这一点,因此它总是很慢。
+---------------+-------------+--------+-------------------------+
| snapshot_date | customer_id | Number | MaxConsecutiveIncreases |
+---------------+-------------+--------+-------------------------+
| 2014-01-01    |       12342 |      0 |                       0 |
| 2014-02-01    |       12342 |     15 |                       1 |
| 2014-03-01    |       12342 |     45 |                       2 |
| 2014-04-01    |       12342 |      0 |                       2 |
| 2014-05-01    |       12342 |     15 |                       2 |
| 2014-06-01    |       12342 |     45 |                       2 |
| 2014-07-01    |       12342 |     75 |                       3 |
| 2014-08-01    |       12342 |    105 |                       4 |
| 2014-09-01    |       12342 |    135 |                       5 |
| 2014-10-01    |       12342 |      0 |                       4 |
| 2014-11-01    |       12342 |      0 |                       3 |
| 2014-12-01    |       12342 |      0 |                       2 |
| 2015-01-01    |       12342 |      0 |                       1 |
| 2015-02-01    |       12342 |      0 |                       0 |
| 2015-03-01    |       12342 |      0 |                       0 |
| 2015-04-01    |       12342 |      0 |                       0 |
+---------------+-------------+--------+-------------------------+