Untuk 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
Kueri rekursif akan membangun baris demi baris dengan menambahkan tanggal mulai dari tanggal pertama hingga terakhir. value
(dan col
) diambil dari tabel asli, yang dibiarkan bergabung pada tanggal. Jika tabel asli tidak memiliki baris untuk tanggal, nilai baris terakhir dalam rekursi akan diambil sebagai gantinya.
Untuk versi yang lebih lama, Anda dapat menggunakan tabel kalender dan subkueri di sebelah kiri bergabung dengan klausa AKTIF untuk mendapatkan nilai terakhir yang ada:
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)
Perbarui
Karena pertanyaannya telah berubah:
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
Pastikan Anda memiliki indeks di (col, dt_id)
. Dalam kasus terbaik itu akan menjadi kunci utama. date_id
di time_table
juga harus diindeks atau kunci utama.