SQL Server:根据前一行增加行值

时间:2018-03-23 07:46:50

标签: sql sql-server

我有一个包含idvalue列的表格。我想创建一个对id进行分组的列。如果行的当前value等于0,则会在ideal_group中创建一个新组。

表:

id | value | ideal_group
1    1       1
2    1       1
3    1       1
4    0       2
5    1       2
6    0       3
7    0       4

我认为解决方案应该是这样的:

SET @n = 1;
SELECT id, 
       CASE 
            WHEN value = 0 THEN @n = @n + 1 
       ELSE @n END AS ideal_group

但我不想使用计数器变量。还有另一种方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

尝试使用以下代码,我假设value列中的值仅为1 s和0 s:

select id,
       value,
       sum(1 - value) over (order by id rows between unbounded preceding and current row) + 1 [ideal_group]
from MY_TABLE

更一般的解决方案(未提及假设):

select id,
       value,
       sum(case value when 0 then 1 else 0 end) over (order by id rows between unbounded preceding and current row) + 1 [ideal_group]
from MY_TABLE

答案 1 :(得分:2)

create table tbl (id int, value int);
insert into tbl values
(1, 1),
(2, 1),
(3, 1),
(4, 0),
(5, 1),
(6, 0),
(7, 0);
GO
7 rows affected
select id,
       value,
       1 + sum(iif(value = 0, 1, 0)) over 
                (order by id rows between unbounded preceding and current row) as ideal_group
from   tbl
GO
id | value | ideal_group
-: | ----: | ----------:
 1 |     1 |           1
 2 |     1 |           1
 3 |     1 |           1
 4 |     0 |           2
 5 |     1 |           2
 6 |     0 |           3
 7 |     0 |           4

dbfiddle here

答案 2 :(得分:0)

如果你颠倒了1和0并且它只有1或0,这将更容易。

declare @T table (id int primary key, val int);
insert into @T values 
       (1, 1)
     , (2, 1)
     , (3, 1)
     , (4, 0)
     , (5, 1)
     , (6, 0)
     , (7, 0);
select t.id, t.val 
     , case when t.val = 0 then 1 else 0 end as trig
     , sum(case when t.val = 0 then 1 else 0 end) over (order by t.id) + 1 as grp
from @T t 
order by t.id; 

id          val         trig        grp
----------- ----------- ----------- -----------
1           1           0           1
2           1           0           1
3           1           0           1
4           0           1           2
5           1           0           2
6           0           1           3
7           0           1           4