Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

encontre as entradas que faltam para os dias úteis e preencha a linha com os valores da data mais próxima


Para esses tipos de consulta, você obtém benefícios de desempenho significativos ao criar uma tabela de calendário contendo todas as datas que você precisará testar. (Se você estiver familiarizado com o termo "tabelas de dimensão", esta é apenas uma dessas tabelas para enumerar todas as datas de interesse.)

Além disso, a consulta como um todo pode se tornar significativamente mais simples.
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 ao seu comentário com um requisito diferente

Obter sempre "o valor acima" é mais fácil, e inserir esses valores em uma tabela é 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
;

Observação: Você pode adicionar WHERE prev_data.gap > 0 para a consulta maior acima para obter apenas as datas que ainda não têm dados.