在sql中的select查询中将列值有条件地自动递增1

在sql中的select查询中将列值有条件地自动递增1,sql,sql-server,tsql,dml,Sql,Sql Server,Tsql,Dml,我有如下输入表: 和在select查询中不更改表的情况下需要如下输出: 您可以从一个CTE开始,它添加一个ROW_NUMBER()列,并过滤掉“nm”为空的行 然后从表中选择并外部连接到CTE,使用行编号列填充计数列。您可以计算根据“nm”是否为空划分的行编号,然后仅在“nm”不为空时显示计算的行编号 示例代码段: 比较所有解决方案的执行计划(使用SQL 2017):-) 我的解决方案是21%;卢克溶液38%;伊恩·福格曼溶液41% 在特定服务器中进行测试后选择您的解决方案! 应该将4计算

我有如下输入表:

在select查询中不更改表的情况下需要如下输出:


您可以从一个CTE开始,它添加一个ROW_NUMBER()列,并过滤掉“nm”为空的行


然后从表中选择并外部连接到CTE,使用行编号列填充
计数
列。

您可以计算根据“nm”是否为空划分的行编号,然后仅在“nm”不为空时显示计算的行编号

示例代码段:

比较所有解决方案的执行计划(使用SQL 2017):-)

我的解决方案是21%;卢克溶液38%;伊恩·福格曼溶液41%

在特定服务器中进行测试后选择您的解决方案!

应该将
4
计算为3吗?你试过什么吗?如果是这样,请向我们展示您的尝试。发布文本而不是图像。我没给你答复,你确定吗。看起来计数会重新开始,它很有效。通过iif(
)对
分区的有趣使用。我不知道这个功能。好吧,你可以使用CASE WHEN代替iif。但是iif更短。是的,我不是指
iif()
我指的是按1或0划分的
分区。按1划分意味着行不被计数,但按0划分意味着行被计数,这似乎是违反直觉的。但出于某种原因,它确实返回了所需的结果。@Papazzo计数确实是从划分的内容开始的。在这种情况下,它是1或0。因此,对于那些有我已经填写了nm。在特定服务器上测试后选择您的解决方案!哈哈,我喜欢;)这一点很重要@Sami,因为一个系统中的最佳解决方案可能是另一个系统中更糟糕的选择。有许多参数与选择最佳解决方案有关。但是,利用我们在这里的问题中得到的信息,我会选择我的解决方案:-)+1一种巧妙的方法,它利用了一个事实,即对值的计数不计算空值。因为这不需要分区,所以这可能就是它更快的原因。这是一个很好的解决方案,但考虑到数据量,我不会把重点放在性能比较上。
declare @T table (id int identity(1,1) primary key, nm varchar(8));
insert into @T (nm) values ('R'),('R'),(null),('R');

select *, 
 iif(nm is null,null,row_number() over (partition by iif(nm is null,1,0) order by id)) as [Count]
from @T
order by id
;WITH CTE AS 
(
    SELECT ID,
           ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY ID) AS [COUNT] 
    FROM [TABLE] WHERE NM IS NOT NULL 
)
SELECT S.ID,
       S.NM,
       CTE.[COUNT] 
FROM [TABLE] AS S LEFT JOIN CTE AS CTE ON S.ID = CTE.ID
drop table if exists T;
create table T(id int, nm nvarchar(10)) 
GO
insert T(id, nm) values (1,'r'),(2,'r'),(3,null),(4,'r')
SELECT * FROM T
GO
-- solution:
select 
    id, nm, 
    CASE WHEN nm is not null then count(nm) over (order by id) ELSE NULL END
from T
GO