Reputation: 371
I have a table:
key dat value
KEY1 01.07.2019 3
KEY2 01.07.2019 null
KEY1 01.08.2019 null
KEY2 01.08.2019 4
KEY1 01.09.2019 null
KEY2 01.09.2019 5
I need to have the value have the last non-null value if there is no value for current month, resulting in this
key dat value
KEY1 01.07.2019 3
KEY2 01.07.2019 null
KEY1 01.08.2019 3 <=
KEY2 01.08.2019 4
KEY1 01.09.2019 3 <=
KEY2 01.09.2019 5
I could do it with cursor, but I believe the right way would be to go with CTE.
Upvotes: 1
Views: 327
Reputation: 1269463
The "correct" way is lag(ignore nulls)
, but SQL Server does not implement that yet.
If the values are always increasing, you can use a cumulative max:
select t.*,
max(value) over (partition by key order by date) as new_value
from t;
That is a special case, the rest of the answer provides more general answers.
Another method uses outer apply
:
select t.*, t2.value
from t outer apply
(select top (1) t2.*
from t t2
where t2.key = t.key and t2.date <= t.date and t2.value is not null
order by t2.date desc
) t2
And a third method uses two levels of window functions:
select t.*, max(value) over (partition by key, not_null_date)
from (select t.*,
max(case when value is not null then date end) over (partition by key order by date) as not_null_date
from t
) t
Upvotes: 4