Как получить номер строки для каждого нулевого значения? - PullRequest
3 голосов
/ 03 мая 2019

Мне нужно получить номер строки для каждой записи нуля по порядку.Перезапустите число, когда получите значение в строке.

Я пытался до сих пор

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 

Я получаю это:

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

Я хочутакой результат

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

Как получить желаемый результат с помощью SQL-запроса?

1 Ответ

3 голосов
/ 03 мая 2019

Этот подход использует COUNT в качестве аналитической функции над столбцом value для генерации "групп" для каждого блока значений NULL.Чтобы увидеть, как это работает, просто запустите SELECT * FROM cte, используя код ниже.Затем, используя эту вычисленную группу, мы используем ROW_NUMBER, чтобы сгенерировать последовательности для значений NULL.Мы упорядочиваем по возрастанию по значению, что будет означать, что каждая последовательность номеров строк NULL всегда будет начинаться с 1, что является желаемым поведением.Для записей со значением не NULL мы просто перетаскиваем это значение в столбец rn.

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;

enter image description here

Демо

...