As @siggemannen mentioned in the comments, you need a date/timestamp or a unique id per ID to make it possible.
Assuming you have a unique id per ID called rn_id, the window function MAX()
with a range clause can help you only if NAME are ordered alphabetically :
select id, max(NAME) over ( partition by ID order by rn_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as NAME
from mytable
Result :
id |
NAME |
1 |
null |
1 |
A |
1 |
A |
1 |
A |
1 |
B |
1 |
B |
Demo here
If not ordered alphabetically then we will need to use two window functions :
The IIF() function will return 1 when a value is present, otherwise it will return zero. The windowed sum will show the running total increasing, which will create a grouping for a value and it's following nulls.
Then first_value()
will catch the last non null value per group :
with cte as (
SELECT
ID,
rn_id,
NAME,
SUM(IIF(NAME IS NULL, 0,1)) OVER (partition by ID ORDER BY rn_id ASC) AS grp
FROM
mytable
)
select id, First_value(NAME) over ( partition by ID, grp order by rn_id) as NAME_
from cte
Demo here