Untuk jenis kueri ini, Anda memperoleh manfaat kinerja yang signifikan dari membuat tabel kalender yang berisi setiap tanggal yang perlu Anda uji. (Jika Anda familiar dengan istilah "tabel dimensi", ini hanyalah salah satu tabel untuk menghitung setiap tanggal yang diinginkan.)
Selain itu, kueri secara keseluruhan dapat menjadi jauh lebih sederhana.
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'
;
EDIT Balas komentar Anda dengan persyaratan berbeda
Untuk selalu mendapatkan "nilai di atas" lebih mudah, dan memasukkan nilai-nilai itu ke dalam tabel cukup mudah...
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
;
Catatan: Anda dapat menambahkan WHERE prev_data.gap > 0
ke kueri yang lebih besar di atas untuk hanya mendapatkan tanggal yang belum memiliki data.