Voor MySQL 8:
with recursive rcte(dt_id, col, value) as (
(
select dt_id, col, value
from mytable
order by dt_id
limit 1
)
union all
select r.dt_id + interval 1 day
, coalesce(t.col, r.col)
, coalesce(t.value, r.value)
from rcte r
left join mytable t on t.dt_id = r.dt_id + interval 1 day
where r.dt_id < (select max(dt_id) from mytable)
)
select r.col, r.dt_id, r.value
from rcte r
order by r.dt_id
De recursieve query bouwt rij voor rij op en verhoogt de datum vanaf de eerste tot de laatste. De value
(en col
) is overgenomen van de originele tabel, die op datum is samengevoegd. Als de oorspronkelijke tabel geen rij voor een datum heeft, wordt in plaats daarvan de waarde van de laatste rij in de recursie genomen.
Voor oudere versies kunt u uw kalendertabel en een subquery in de linker joins ON-clausule gebruiken om de laatste bestaande waarden te krijgen:
select b.col, c.date_id, b.value
from time_table c
left join balance b on b.dt_id = (
select max(dt_id)
from balance b1
where b1.dt_id <= c.date_id
)
where c.date_id >= (select min(dt_id) from balance)
and c.date_id <= (select max(dt_id) from balance)
Bijwerken
Sinds de vraag is gewijzigd:
select b.col, c.date_id, b.value
from (
select col, min(dt_id) as min_dt, max(dt_id) as max_dt
from balance
group by col
) i
join time_table c
on c.date_id >= i.min_dt
and c.date_id <= i.max_dt
left join balance b
on b.col = i.col
and b.dt_id = (
select max(dt_id)
from balance b1
where b1.dt_id <= c.date_id
and b1.col = i.col
)
order by b.col, c.date_id
Zorg ervoor dat je een index hebt op (col, dt_id)
. In het beste geval zou dit de primaire sleutel zijn. date_id
in de time_table
moet ook worden geïndexeerd of de primaire sleutel.