Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Finden Sie die fehlenden Einträge für die Arbeitstage und füllen Sie die Zeile mit den Werten des nächstliegenden Datums

Bei diesen Abfragetypen erzielen Sie erhebliche Leistungsvorteile, wenn Sie eine Kalendertabelle erstellen, die jedes Datum enthält, das Sie jemals testen müssen. (Wenn Sie mit dem Begriff „Maßtabellen“ vertraut sind, ist dies nur eine solche Tabelle, um alle interessierenden Daten aufzuzählen.)

Auch die Abfrage insgesamt kann deutlich einfacher werden.

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

BEARBEITEN Antworten Sie auf Ihren Kommentar mit einer anderen Anforderung

Es ist einfacher, immer "den obigen Wert" zu erhalten, und diese Werte in eine Tabelle einzufügen, ist einfach genug ...

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
;

Hinweis: Sie könnten WHERE prev_data.gap > 0 hinzufügen zur größeren Abfrage oben, um nur Daten zu erhalten, für die noch keine Daten vorhanden sind.