如何在T-SQL中的特定值上创建此特殊计数器?

时间:2017-01-10 18:15:33

标签: sql sql-server tsql count counter

我有问题,我一直在努力工作几个小时。 我正在尝试在临时表的列上创建一个特殊的计数器,我的表有很多列,其中一列是col1:

col1 |
######
X    | 
X    | 
A    | 
B    | 
X    | 
C    | 
X    | 
D    | 

特殊计数器应该是这样的:

col1 | counter
###############
X    | 1
X    | 2
A    | 2
B    | 2
X    | 3
C    | 3
X    | 4
D    | 4

它应仅计算“X”值,并保持不变,以防该值为其他任何值。

我尝试了很多东西,我得到的最接近的是通过仅使用计数器创建另一个临时表,然后将其与原始表连接,但结果是这样的:

col1 | counter
###############
X    | 1
X    | 2
A    | NULL
B    | NULL
X    | 3
C    | NULL
X    | 4
D    | NULL

那么,我该如何创建这个特殊的计数器?

3 个答案:

答案 0 :(得分:4)

这是一个更新声明。每次遇到X时,该语句都会递增变量,并使用正确的值更新每一行。

declare @counter int = 0;
update   #temp
set      counter = @counter
       , @counter += case when col1 = 'X' then 1
                          else 0
                     end;

答案 1 :(得分:3)

<{1}}中的{p> Row_Number()应该可以解决问题。

您会注意到我添加了字段ID来维护序列。

CASE

返回

Declare @YourTable table (ID int,col1 varchar(25))
Insert Into @YourTable values
(1,'X'),
(2,'X'),
(3,'A'),
(4,'B'),
(5,'X'),
(6,'C'),
(7,'X'),
(8,'D')

Select ID,Col1
      ,Counter = max(counter) over (Order By ID)
 From (
       Select ID
             ,col1
             ,counter = case when col1='X' then row_number() over (Partition By col1 Order by ID) else null end
        From  @YourTable
      ) A
 Order By ID

答案 2 :(得分:2)

有更简单,更直接的解决方案。我们只需要一点观察:计数器等于前一行中X的计数:

select id, 
       col1,
       (select count(*) from @t where id <= t.id and col1 = 'X') as counter
from @t t