Вот как бы я это сделал.Это может помочь в других подобных проблемах (линейная интерполяция), где нельзя предполагать, что «значение» увеличивается со временем.Для одометра это предположение имеет смысл, и решение Гордона Линоффа проще;Я предлагаю это решение для других приложений, где «количество» может уменьшаться, а также увеличиваться со временем.
with
sample_data(last_updated_date, odometer) as (
select to_date('05-OCT-18', 'dd-MON-rr'), 47174.77 from dual union all
select to_date('08-OCT-18', 'dd-MON-rr'), null from dual union all
select to_date('12-OCT-18', 'dd-MON-rr'), 50246.37 from dual union all
select to_date('15-OCT-18', 'dd-MON-rr'), null from dual union all
select to_date('19-OCT-18', 'dd-MON-rr'), 53743.11 from dual union all
select to_date('21-OCT-18', 'dd-MON-rr'), null from dual union all
select to_date('22-OCT-18', 'dd-MON-rr'), null from dual union all
select to_date('25-OCT-18', 'dd-MON-rr'), 58789.22 from dual
)
, prep(last_updated_date, odometer, prev_date, next_date, prev_odo, next_odo) as (
select last_updated_date, odometer,
case when odometer is null
then max(nvl2(odometer, last_updated_date, null))
over (order by last_updated_date) end,
case when odometer is null
then min(nvl2(odometer, last_updated_date, null))
over (order by last_updated_date
rows between 1 following and unbounded following) end,
last_value(odometer ignore nulls) over (order by last_updated_date),
first_value(odometer ignore nulls) over (order by last_updated_date
rows between 1 following and unbounded following)
from sample_data
)
select last_updated_date,
nvl( odometer,
round(prev_odo + (next_odo - prev_odo) *
(last_updated_date - prev_date) / (next_date - prev_date), 2)
) as odometer
from prep
order by last_updated_date
;
ВЫХОД
LAST_UPDATED_DATE ODOMETER
----------------- ----------
05-OCT-18 47174.77
08-OCT-18 48491.17
12-OCT-18 50246.37
15-OCT-18 51744.97
19-OCT-18 53743.11
21-OCT-18 55425.15
22-OCT-18 56266.17
25-OCT-18 58789.22