I need to get row number for each record of null by sequence. Restart number when get a value in the row.
I have tried so far
select * , ROW_NUMBER() over (order by id) rn from @tbl select * , ROW_NUMBER() over (partition by value order by id) rn from @tbl
declare @tbl table(id int, value int) insert into @tbl values (1, null), (2, null), (3, null), (4, 1),(5, null), (6, null), (7, 1), (8, null), (9, null), (10, null) select * , ROW_NUMBER() over (partition by value order by id) rn from @tbl
I’m getting this:
id, value, rn 1 NULL 1 2 NULL 2 3 NULL 3 4 1 4 5 NULL 5 6 NULL 6 7 1 7 8 NULL 8 9 NULL 9 10 NULL 10
I want a result like this
id, value, rn 1 NULL 1 2 NULL 2 3 NULL 3 4 1 1 5 NULL 1 6 NULL 2 7 1 1 8 NULL 1 9 NULL 2 10 NULL 3
How can I get desired result with sql query?
Advertisement
Answer
This approach uses COUNT
as an analytic function over the value
column to generate “groups” for each block of NULL
values. To see how this works, just run SELECT * FROM cte
using the code below. Then, using this computed group, we use ROW_NUMBER
to generate the sequences for the NULL
values. We order ascending by the value, which would mean that each NULL
row number sequence would always begin with 1, which is the behavior we want. For records with a non NULL
value, we just pull that value across into the rn
column.
WITH cte AS ( SELECT *, COUNT(value) OVER (ORDER BY id) vals FROM @tbl ) SELECT id, value, CASE WHEN value IS NULL THEN ROW_NUMBER() OVER (PARTITION BY vals ORDER BY value) ELSE value END AS rn FROM cte ORDER BY id;