Mysql
 sql >> Datenbank >  >> RDS >> Mysql

mysql generiert fehlende Daten mit dem vorherigen Wert

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

db-fiddle

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)

db-fiddle

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

db-fiddle

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.