在表格上执行插值,按第3个字段分组

时间:2014-04-03 10:32:39

标签: sql sql-server linear-interpolation

我有一个包含三列的SQL Server 2008+表:

Delta (float)
Rate (float)
and Date (datetime)

我需要能够为给定日期生成所有delta的费率表,必要时进行插值。我可以为Delta的单个值做得很好,但同时为所有Delta做这件事让我很难受。

一些示例数据是

Rate    ForwardDate             Delta
1.3528  2013-09-30 00:00:00.000 -0.9
1.3528  2013-09-30 00:00:00.000 -0.75
1.3528  2013-09-30 00:00:00.000 -0.5
1.3528  2013-09-30 00:00:00.000 -0.25
1.3528  2013-09-30 00:00:00.000 -0.1
7.121   2013-10-30 00:00:00.000 -0.9
7.152   2013-10-30 00:00:00.000 -0.75
7.387   2013-10-30 00:00:00.000 -0.5
7.972   2013-10-30 00:00:00.000 -0.25
8.564   2013-10-30 00:00:00.000 -0.1
6.972   2013-12-30 00:00:00.000 -0.9
7.035   2013-12-30 00:00:00.000 -0.75
7.405   2013-12-30 00:00:00.000 -0.5
8.275   2013-12-30 00:00:00.000 -0.25
9.187   2013-12-30 00:00:00.000 -0.1
7.185   2014-03-30 00:00:00.000 -0.9
7.321   2014-03-30 00:00:00.000 -0.75
7.82    2014-03-30 00:00:00.000 -0.5
8.919   2014-03-30 00:00:00.000 -0.25
10.075  2014-03-30 00:00:00.000 -0.1
7.755   2014-09-30 00:00:00.000 -0.9
7.92    2014-09-30 00:00:00.000 -0.75
8.485   2014-09-30 00:00:00.000 -0.5
9.76    2014-09-30 00:00:00.000 -0.25
11.175  2014-09-30 00:00:00.000 -0.1

到目前为止,我想出的最好的是:

(
SELECT Delta, ( DATEDIFF(d, @PreviousDate, @ForwardDate) * NextRate 
                   + DATEDIFF(d, @ForwardDate, @NextDate) * PreviousRate
                   ) / DATEDIFF(d, @PreviousDate, @NextDate) AS Rate

FROM 
 (SELECT Main.Delta AS Delta, PR.Rate AS PreviousRate, NR.Rate AS NextRate
  FROM @RatesTable Main
  INNER JOIN @RatesTable PR on PR.Delta = Main.Delta AND PR.ForwardDate = @PreviousDate
  INNER JOIN @RatesTable NR on NR.Delta = Main.Delta AND NR.ForwardDate = @NextDate) AS PrevNextRateTable);

@NextDate@PreviousDate来自之前的计算,以确定最接近测试日期(@ForwardDate)的表格中的日期。这是必要的,因为我们需要确保所有插值都在相同的两个日期之间(如果其中一个日期缺少一个值,则给出NULL)。我不想在每个delta值的不同日期之间进行插值。

这给了我似乎是结果的交叉连接

Delta   Rate
-0.9    7.742609
-0.75   7.906979
-0.5    8.470543
-0.25   9.741717
-0.1    11.15109
-0.9    7.742609
-0.75   7.906979
-0.5    8.470543
-0.25   9.741717
-0.1    11.15109
-0.9    7.742609
-0.75   7.906979
-0.5    8.470543
-0.25   9.741717
-0.1    11.15109
-0.9    7.742609
-0.75   7.906979
-0.5    8.470543
-0.25   9.741717
-0.1    11.15109
-0.9    7.742609
-0.75   7.906979
-0.5    8.470543
-0.25   9.741717
-0.1    11.15109

每个delta有5个结果。如果有必要的话,我可以SELECT DISTINCT这个,但不能帮助我,但是我觉得这是在作弊,我做错了什么。有没有更好的方法可以消除SELECT DISTINCT的需要?

1 个答案:

答案 0 :(得分:1)

试试这个:

SELECT Delta, ( DATEDIFF(d, @PreviousDate, @ForwardDate) * NextRate 
                   + DATEDIFF(d, @ForwardDate, @NextDate) * PreviousRate
                   ) / DATEDIFF(d, @PreviousDate, @NextDate) AS Rate

FROM 
 (SELECT Main.Delta AS Delta, PR.Rate AS PreviousRate, NR.Rate AS NextRate
  FROM @RatesTable Main
  INNER JOIN @RatesTable PR on PR.Delta = Main.Delta AND PR.ForwardDate = @PreviousDate
  INNER JOIN @RatesTable NR on NR.Delta = Main.Delta AND NR.ForwardDate = @NextDate) AS PrevNextRateTable
GROUP BY Delta,
        ( DATEDIFF (d, @PreviousDate, @ForwardDate) * NextRate 
                   + DATEDIFF(d, @ForwardDate, @NextDate) * PreviousRate
                   ) / DATEDIFF(d, @PreviousDate, @NextDate) ;