Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

trova le voci mancanti per i giorni lavorativi e riempi la riga con i valori della data più vicina

Per questi tipi di query ottieni notevoli vantaggi in termini di prestazioni dalla creazione di una tabella di calendario contenente tutte le date che dovrai testare. (Se hai familiarità con il termine "tabelle delle dimensioni", questa è solo una di queste tabelle per enumerare ogni data di interesse.)

Inoltre, la query nel suo insieme può diventare notevolmente più semplice.

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'
;

MODIFICA Rispondi al tuo commento con un requisito diverso

Ottenere sempre "il valore sopra" è più facile e inserire quei valori in una tabella è abbastanza facile...

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: Puoi aggiungere WHERE prev_data.gap > 0 alla query più grande sopra per ottenere solo le date che non hanno già dati.