根据Tom H.的假设,您真正想要的是线性插值,并且不仅缺少年份,而且还缺少月份,因此您需要基于每个计算月份,而不是年份。
对于下面的代码,我假设您有两个表(其中一个可以作为视图的一部分计算):
- Yield:包含实际数据并以数字形式存储PeriodM,而不是名称。如果您在那里存储PeriodName,则只需要加入该表即可。
- Period(可以像所示那样在视图中计算):存储期间名称和它代表的月数
以下代码必须有效(您只需基于它创建一个视图):
WITH "Period" (PeriodM, PeriodName) AS (
SELECT 01, '1 mo'
UNION ALL SELECT 02, '2 mo'
UNION ALL SELECT 03, '3 mo'
UNION ALL SELECT 06, '6 mo'
UNION ALL SELECT 12, '1 yr'
UNION ALL SELECT 24, '2 yr'
UNION ALL SELECT 36, '3 yr'
UNION ALL SELECT 48, '4 yr'
UNION ALL SELECT 60, '5 yr'
UNION ALL SELECT 72, '6 yr'
UNION ALL SELECT 84, '7 yr'
UNION ALL SELECT 96, '8 yr'
UNION ALL SELECT 108, '9 yr'
UNION ALL SELECT 120, '10 yr'
UNION ALL SELECT 240, '20 yr'
UNION ALL SELECT 360, '30 yr'
)
, "Yield" (ID, PeriodM, Date, Value) AS (
SELECT 101, 01 , '2009-05-01', 0.06
UNION ALL SELECT 102, 03 , '2009-05-01', 0.16
UNION ALL SELECT 103, 06 , '2009-05-01', 0.31
UNION ALL SELECT 104, 12 , '2009-05-01', 0.49
UNION ALL SELECT 105, 24 , '2009-05-01', 0.92
UNION ALL SELECT 346, 36 , '2009-05-01', 1.39
UNION ALL SELECT 237, 60 , '2009-05-01', 2.03
UNION ALL SELECT 238, 84 , '2009-05-01', 2.72
UNION ALL SELECT 239,120 , '2009-05-01', 3.21
UNION ALL SELECT 240,240 , '2009-05-01', 4.14
UNION ALL SELECT 250,360 , '2009-05-01', 4.09
)
, "ReportingDate" ("Date") AS (
SELECT DISTINCT Date FROM "Yield"
)
SELECT d.Date, p.PeriodName,
CAST(
COALESCE(y_curr.Value,
( (p.PeriodM - y_prev.PeriodM) * y_prev.Value
+ (y_next.PeriodM - p.PeriodM) * y_next.Value
) / (y_next.PeriodM - y_prev.PeriodM)
) AS DECIMAL(9,4)
) AS Value
FROM "Period" p
CROSS JOIN "ReportingDate" d
LEFT JOIN "Yield" y_curr
ON y_curr.Date = d.Date
AND y_curr.PeriodM = p.PeriodM
LEFT JOIN "Yield" y_prev
ON y_prev.ID = (SELECT TOP 1 y.ID FROM Yield y WHERE y.Date = d.Date AND y.PeriodM <= p.PeriodM ORDER BY y.PeriodM DESC)
LEFT JOIN "Yield" y_next
ON y_next.ID = (SELECT TOP 1 y.ID FROM Yield y WHERE y.Date = d.Date AND y.PeriodM >= p.PeriodM ORDER BY y.PeriodM ASC)