T-SQL:行号仅适用于具有填充字段的行

时间:2019-03-14 16:20:05

标签: sql-server tsql

我有一个带有整数类型主键和两个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,因此可以使用所有当前功能)

4 个答案:

答案 0 :(得分: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 :(得分:1)

按照ID的顺序:

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

答案 2 :(得分: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

答案 3 :(得分: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