Sql server 如果月内日期不断增加,您可以使用如下窗口功能: select t.id, ind, lvl, result, dat, case when result = 1 then row_number() over (partition by grp order by id) else 0 end x from ( select t.*, dense_rank() over (order by e, result) grp from ( select t.*, row_number() over (order by id) - row_number() over (partition by ind, lvl, result order by id) e from your_table t order by id) t ) t;

Sql server 如果月内日期不断增加,您可以使用如下窗口功能: select t.id, ind, lvl, result, dat, case when result = 1 then row_number() over (partition by grp order by id) else 0 end x from ( select t.*, dense_rank() over (order by e, result) grp from ( select t.*, row_number() over (order by id) - row_number() over (partition by ind, lvl, result order by id) e from your_table t order by id) t ) t;,sql-server,tsql,Sql Server,Tsql,假设每月的日期不断增加,您可以使用如下窗口函数: select t.id, ind, lvl, result, dat, case when result = 1 then row_number() over (partition by grp order by id) else 0 end x from ( select t.*, dense_rank() over (order by e, result) grp from ( select t.*, row_num

假设每月的日期不断增加,您可以使用如下窗口函数:

select 
  t.id, ind, lvl, result, dat,
  case when result = 1 then row_number() over (partition by grp order by id) else 0 end x
from (
select t.*, 
  dense_rank() over (order by e, result) grp
from (
select 
  t.*,
  row_number() over (order by id) - row_number() over (partition by ind, lvl, result order by id) e
from your_table t
order by id) t ) t;

我们是否保证所有的
date
值都是日期,并且总是每个月的最后一天?@Damien_the_unsiver是的,它总是每个月的最后一天!我们是否保证所有的
date
值都是日期,并且总是每个月的最后一天?@Damien_the_unsiver是的,它总是每个月的最后一天!谢谢你的回答!谢谢你的回答!感谢达米恩的不信者你的回答!感谢达米恩的不信者你的回答!谢谢你的回答!谢谢你的回答!
declare @t table (id int not null,ind int not null,lvl varchar(13) not null,
result int not null,date date not null)
insert into @t(id,ind,lvl,result,date) values
(1 ,1,'a',3,'20170131'),    (2 ,1,'a',3,'20170228'),    (3 ,1,'a',1,'20170331'),
(4 ,1,'a',1,'20170430'),    (5 ,1,'a',1,'20170531'),    (6 ,1,'b',1,'20170131'),
(7 ,1,'b',3,'20170228'),    (8 ,1,'b',3,'20170331'),    (9 ,1,'b',1,'20170430'),
(10,1,'b',1,'20170531'),    (11,2,'a',3,'20170131'),    (12,2,'a',1,'20170228'),
(13,2,'a',3,'20170331'),    (14,2,'a',1,'20170430'),    (15,2,'a',3,'20170531')

;With Tweaked as (
    select
        *,
        DATEADD(day,1,date) as dp1d
    from
        @t
), Numbers(n) as (
    select 0 union all select 1 union all select 2 union all select 3 union all select 4
    union all
    select 5 union all select 6 union all select 7 union all select 8 union all select 9
)
select
    id,     ind,        lvl,        result,     date,
    COALESCE(
        (select MIN(n) from Numbers n1
        inner join Tweaked t2
        on
            t2.ind = t1.ind and
            t2.lvl = t1.lvl and
            t2.dp1d = DATEADD(month,-n,t1.dp1d)
        where
            t2.result != 1
        ),
        1) as [BadResultRemainsFor%Months]
from
    Tweaked t1
id          ind         lvl           result      date       BadResultRemainsFor%Months
----------- ----------- ------------- ----------- ---------- --------------------------
1           1           a             3           2017-01-31 0
2           1           a             3           2017-02-28 0
3           1           a             1           2017-03-31 1
4           1           a             1           2017-04-30 2
5           1           a             1           2017-05-31 3
6           1           b             1           2017-01-31 1
7           1           b             3           2017-02-28 0
8           1           b             3           2017-03-31 0
9           1           b             1           2017-04-30 1
10          1           b             1           2017-05-31 2
11          2           a             3           2017-01-31 0
12          2           a             1           2017-02-28 1
13          2           a             3           2017-03-31 0
14          2           a             1           2017-04-30 1
15          2           a             3           2017-05-31 0
DATEADD(month,DATEDIFF(month,0,date),0) as dp1d
    ;WITH tb(id,ind,lvl,result,date) AS(
        select 1,1,'a',3,'2017-01-31' UNION
        select 2,1,'a',3,'2017-02-28' UNION
        select 3,1,'a',1,'2017-03-31' UNION
        select 4,1,'a',1,'2017-04-30' UNION
        select 5,1,'a',1,'2017-05-31' UNION
        select 6,1,'b',1,'2017-01-31' UNION
        select 7,1,'b',3,'2017-02-28' UNION
        select 8,1,'b',3,'2017-03-31' UNION
        select 9,1,'b',1,'2017-04-30' UNION
        select 10,1,'b',1,'2017-05-31' UNION
        select 11,2,'a',3,'2017-01-31' UNION
        select 12,2,'a',1,'2017-02-28' UNION
        select 13,2,'a',3,'2017-03-31' UNION
        select 14,2,'a',1,'2017-04-30' UNION
        select 15,2,'a',3,'2017-05-31' 
    )
    SELECT t.id,t.ind,t.lvl,t.result,t.date
    ,CASE WHEN t.isMatched=1 THEN ROW_NUMBER()OVER(PARTITION BY t.ind,t.lvl,t.id-t.rn ORDER BY t.id) ELSE 0 END
    FROM (
        SELECT t1.*,c.MonthDiff,CASE WHEN c.MonthDiff=t1.result THEN 1 ELSE 0 END  AS isMatched
               ,CASE WHEN c.MonthDiff=t1.result THEN ROW_NUMBER()OVER(PARTITION BY t1.ind,t1.lvl,CASE WHEN c.MonthDiff=t1.result THEN 1 ELSE 0 END ORDER BY t1.id) ELSE null END AS rn
        FROM tb AS t1
        LEFT JOIN tb AS t2 ON t1.ind=t2.ind AND t1.lvl=t2.lvl AND t2.id=t1.id-1
        CROSS APPLY(VALUES(ISNULL(DATEDIFF(MONTH,t2.date,t1.date),1))) c(MonthDiff)

    ) AS t
    ORDER BY t.id
id ind lvl result date ----------- ----------- ---- ----------- ---------- -------------------- 1 1 a 3 2017-01-31 0 2 1 a 3 2017-02-28 0 3 1 a 1 2017-03-31 1 4 1 a 1 2017-04-30 2 5 1 a 1 2017-05-31 3 6 1 b 1 2017-01-31 1 7 1 b 3 2017-02-28 0 8 1 b 3 2017-03-31 0 9 1 b 1 2017-04-30 1 10 1 b 1 2017-05-31 2 11 2 a 3 2017-01-31 0 12 2 a 1 2017-02-28 1 13 2 a 3 2017-03-31 0 14 2 a 1 2017-04-30 1 15 2 a 3 2017-05-31 0
select 
  t.id, ind, lvl, result, dat,
  case when result = 1 then row_number() over (partition by grp order by id) else 0 end x
from (
select t.*, 
  dense_rank() over (order by e, result) grp
from (
select 
  t.*,
  row_number() over (order by id) - row_number() over (partition by ind, lvl, result order by id) e
from your_table t
order by id) t ) t;