Я имею в виду generate_series()
и функции окна:
select
n.name,
s.date,
coalesce(t.balance, lag(balance) over(partition by n.name order by s.date) balance
from (select generate_series(min(date), max(date), interval '1 day') date from mytable) s
cross join (select distinct name from mytable) n
left join mytable t on t.name = n.name and t.date = s.date
order by n.name, s.date
Если у вас может быть несколько пропущенных дат подряд, тогда нужно немного больше логик c - это в основном эмулирует lag()
с опцией ignore nulls
:
select
name,
date,
coalesce(balance, first_value(balance) over(partition by name, grp)) balance
from (
select
n.name,
s.date,
t.balance,
sum( (t.balance is not null)::int ) over(partition by n.name order by s.date) grp
from (select generate_series(min(date), max(date), interval '1 day') date from mytable) s
cross join (select distinct name from mytable) n
left join mytable t on t.name = n.name and t.date = s.date
) t
order by name, date