문제

I have a SQL Server 2008+ table with three columns:

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

I need to be able to generate a table of rates for all delta for a given date, interpolating if necessary. I can do this fine for single values of Delta, but doing it for all Delta at the same time is stumping me.

Some example data is

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

The best I have come up with so far is:

(
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);

Where @NextDate and @PreviousDate are from an earlier calculation to determine the dates in the table nearest to the test date (@ForwardDate). This is needed, as we need to ensure that all interpolations are between the same two dates (giving NULL if one value is missing on one of the dates). I don't want to interpolate between different dates for each value of delta.

This gives me what appears to be a cross join of results

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

with 5 results for each delta. I can SELECT DISTINCT this if necessary, but can't help but think it's cheating and I'm doing something wrong. Is there any better way that eliminates the need for SELECT DISTINCT?

도움이 되었습니까?

해결책

Try this:

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) ;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top