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

How to create this special counter on a specific value in T-SQL?

我遇到了几个小时都在努力解决的问题。 我正在尝试在临时 table 的列上创建一个特殊计数器,我的 table 有很多列,其中之一是 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" 值,并保持不变以防其他值。

我尝试了很多东西,最接近的是创建另一个只有计数器的临时文件 table,然后将它与原来的临时文件合并,但结果是这样的:

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

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

Row_Number()CASE 内应该可以解决问题。

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

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

Returns

ID  Col1    Counter
1   X       1
2   X       2
3   A       2
4   B       2
5   X       3
6   C       3
7   X       4
8   D       4

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

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

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

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