Für 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
Die rekursive Abfrage baut Zeile für Zeile auf und erhöht das Datum vom ersten bis zum letzten Datum. Der value
(und col
) wird aus der ursprünglichen Tabelle entnommen, die am Datum zusammengefügt bleibt. Wenn die ursprüngliche Tabelle keine Zeile für ein Datum hat, wird stattdessen der Wert der letzten Zeile in der Rekursion genommen.
Für ältere Versionen können Sie Ihre Kalendertabelle und eine Unterabfrage in der Left Joins ON-Klausel verwenden, um die letzten vorhandenen Werte zu erhalten:
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)
Aktualisieren
Da sich die Frage geändert hat:
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
Stellen Sie sicher, dass Sie einen Index für (col, dt_id)
haben . Im besten Fall wäre es der Primärschlüssel. date_id
in der time_table
sollte ebenfalls indiziert oder der Primärschlüssel sein.