sql >> Base de Datos >  >> RDS >> Sqlserver

encuentre las entradas que faltan para los días hábiles y complete la fila con los valores de la fecha más cercana

Para estos tipos de consultas, obtiene importantes beneficios de rendimiento al crear una tabla de calendario que contiene todas las fechas que necesitará probar. (Si está familiarizado con el término "tablas de dimensiones", esta es solo una de esas tablas para enumerar todas las fechas de interés).

Además, la consulta en su conjunto puede volverse significativamente más simple.

SELECT
   cal.calendar_date   AS data_date,
   CASE WHEN prev_data.gap <= next_data.gap
        THEN prev_data.data_value
        ELSE COALESCE(next_data.data_value, prev_data.data_value)
   END
       AS data_value
FROM
    calendar   AS cal
OUTER APPLY
(
    SELECT TOP(1)
        data_date,
        data_value,
        DATEDIFF(DAY, data_date, cal.calendar_date)   AS gap
    FROM
        data_table
    WHERE
        data_date <= cal.calendar_date
    ORDER BY
        data_date DESC
)
   prev_data
OUTER APPLY
(
    SELECT TOP(1)
        data_date,
        data_value,
        DATEDIFF(DAY, cal.calendar_date, data_date)   AS gap
    FROM
        data_table
    WHERE
        data_date >  cal.calendar_date
    ORDER BY
        data_date ASC
)
   next_data
WHERE
   cal.calendar_date BETWEEN '2015-01-01' AND '2015-12-31'
;

EDITAR Responda a su comentario con un requisito diferente

Obtener siempre "el valor anterior" es más fácil, e insertar esos valores en una tabla es bastante fácil...

INSERT INTO
    data_table
SELECT
   cal.calendar_date,
   prev_data.data_value
FROM
    calendar   AS cal
CROSS APPLY
(
    SELECT TOP(1)
        data_date,
        data_value
    FROM
        data_table
    WHERE
        data_date <= cal.calendar_date
    ORDER BY
        data_date DESC
)
   prev_data
WHERE
       cal.calendar_date BETWEEN '2015-01-01' AND '2015-12-31'
   AND cal.calendar_date <> prev_data.data_date
;

Nota: Podría agregar WHERE prev_data.gap > 0 a la consulta más grande anterior para obtener solo fechas que aún no tienen datos.