sql >> Base de Datos >  >> RDS >> Mysql

mysql genera fechas faltantes con valor anterior

Para 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

La consulta recursiva construirá fila por fila incrementando la fecha a partir de la primera fecha hasta la última. El value (y col ) se toma de la tabla original, que se deja unida en fecha. Si la tabla original no tiene una fila para una fecha, en su lugar se toma el valor de la última fila en la recursividad.

Para versiones anteriores, puede usar su tabla de calendario y una subconsulta en la cláusula ON de uniones izquierda para obtener los últimos valores existentes:

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

Actualizar

Dado que la pregunta ha cambiado:

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

Asegúrese de tener un índice en (col, dt_id) . En el mejor de los casos, sería la clave principal. date_id en el time_table también debe ser indexado o la clave principal.