【问题标题】:SQL Server: Increment row value depending on previous rowSQL Server:根据前一行增加行值
【发布时间】:2018-03-23 07:46:49
【问题描述】:

我有一个包含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

但我不想使用计数器变量。有没有其他方法可以解决这个问题?

【问题讨论】:

  • 当第一行有0时应该返回什么? 0 还是 1?

标签: sql sql-server


【解决方案1】:

试试下面的代码,我假设value 列中的值只有1s 和0s:

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

【讨论】:

  • @PaulKaram 您的建议也行不通,我在此列中添加 1,这与 OP 想要的完全一样 :)
【解决方案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 行受影响
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
编号 |价值 |理想组 -: | ----: | ----------: 1 | 1 | 1 2 | 1 | 1 3 | 1 | 1 4 | 0 | 2 5 | 1 | 2 6 | 0 | 3 7 | 0 | 4

dbfiddle here

【讨论】:

  • 最后一句话,为什么每个人都使用rows between unbounded preceding and current row 而不是较短的rows unbounded preceding 语法?这里current row 的默认值很好:-)
【解决方案3】:

如果你把 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

【讨论】:

  • 你应该添加rows unbounded preceding,否则默认为range unbounded preceding,可能效率较低。并且可能返回不同的结果,例如使用(6,0) 添加第二行。
  • @dnoeth 我无法添加第二行。我把它作为主键。如果他们没有独特的排序,那么这个问题就没有多大意义。
  • 当然,在这种情况下,但普遍的规则仍然是除非你真的需要,否则不要使用RANGE。优化器可能不知道唯一性,然后应用 RANGE 逻辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 2021-08-31
  • 1970-01-01
相关资源
最近更新 更多