これらのタイプのクエリでは、テストする必要があるすべての日付を含むカレンダー テーブルを作成すると、パフォーマンスが大幅に向上します。 (「ディメンション テーブル」という用語に精通している場合、これは関心のあるすべての日付を列挙するテーブルの 1 つにすぎません)
また、クエリ全体が大幅に簡素化されます。
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' ;
プレ>編集 別の要件でコメントに返信してください
常に「上の値」を取得する方が簡単で、それらの値をテーブルに挿入するのは簡単です...
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 ;
プレ>注:
WHERE prev_data.gap > 0
を追加できます 上記のより大きなクエリに、まだデータがない日付のみを取得します。