T-SQL:仅对具有填充字段的行的行号

问题描述 投票:-1回答:4

我有一个表,其主键类型为integer,还有两个varchar列,如下所示:

id   name    remarks 
-------------------------
1    text1   
2    text2   anyRemarks
3    text3   
4    text4   anyRemarks
5    text5
6    text6
7    text7   anyRemarks

只有部分言论被填补。

现在我想要一个计算的行号,但仅适用于已填充备注的行。我需要结果中的所有行,但只有在填写备注时才应增加计数器。所以期望的结果是:

id   name    remarks     counter
----------------------------------
1    text1               0
2    text2   anyRemarks  1
3    text3               0
4    text4   anyRemarks  2
5    text5               0
6    text6               0
7    text7   anyRemarks  3

我的方法是使用row_number并执行如下选择:

SELECT 
    id, name, remarks, 
    ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS counter 
FROM 
    table

但这填补了任何一行的反击。

我需要使用子选择吗?

还有其他建议吗?

(引擎是SQL Server 2017,因此可以使用所有当前功能)

sql-server tsql
4个回答
3
投票

获得结果的一种可能方法:

输入:

CREATE TABLE #Table (
    id int,
    name varchar(10),    
    remarks varchar(50)
)
INSERT INTO #Table
    (id, name, remarks)
VALUES
    (1, 'text1', NULL),
    (2, 'text2', 'anyRemarks'),
    (3, 'text3', NULL),
    (4, 'text4', 'anyRemarks'),
    (5, 'text5', NULL),
    (6, 'text6', NULL),
    (7, 'text7', 'anyRemark')

声明:

SELECT 
    id,
    name,
    remarks,
    CASE
        WHEN remarks IS NULL THEN 0 
        ELSE ROW_NUMBER() OVER (PARTITION BY CASE WHEN remarks is NULL THEN 0 ELSE 1 END ORDER BY id)
    END AS [Rn]
FROM #Table
ORDER BY id

输出:

id  name    remarks     Rn
1   text1   NULL        0
2   text2   anyRemarks  1
3   text3   NULL        0
4   text4   anyRemarks  2
5   text5   NULL        0
6   text6   NULL        0
7   text7   anyRemark   3

1
投票

按ids的顺序:

SELECT 
  t.id, t.name, t.remarks, 
  case 
    when t.remarks is null then 0
    else (select count(*) from table where remarks is not null and id < t.id) + 1 
  end as counter 
FROM table t
ORDER BY t.id

或者使用UNION ALL:

select *, 0 as counter from [table] where remarks is null
union all
select *, row_number() OVER(ORDER BY (id)) from [table] where remarks is not null
order by id

1
投票

您可以使用窗口函数SUM获取运行总计,然后使用CASE中的SELECT语句来检查是否应显示运行总计。

;with cte as
(
    select  *, SUM(case when remarks is null then 0 else 1 end) OVER (ORDER BY id)numRemarks 
    from #Table
)

select id, name, remarks, case when remarks is null then 0 else numRemarks end as counter 
from cte

0
投票

另一个简单的选择是使用countover子句:

SELECT  Id, 
        Name, 
        Remarks, 
        CASE WHEN Remarks IS NULL THEN 0 
        ELSE COUNT(Remarks) OVER(ORDER BY Id) END As Rn
FROM #Table
© www.soinside.com 2019 - 2024. All rights reserved.