Pro tyto typy dotazů získáte významné výhody z hlediska výkonu vytvořením tabulky kalendáře obsahující každé datum, které kdy budete potřebovat otestovat. (Pokud jste obeznámeni s termínem „tabulky dimenzí“, toto je pouze jedna taková tabulka pro výčet každého data zájmu.)
Dotaz jako celek se také může výrazně zjednodušit.
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'
;
UPRAVIT Odpovězte na svůj komentář s jiným požadavkem
Vždy získat "hodnotu výše" je snazší a vložit tyto hodnoty do tabulky je dost snadné...
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
;
Poznámka: Můžete přidat WHERE prev_data.gap > 0
na větší dotaz výše, abyste získali pouze data, která ještě data neobsahují.