根据SQL中的返回值计算价格指数

时间:2017-03-10 19:51:51

标签: tsql

我正在尝试根据我可用的回报来计算价格指数。

这是原始数据

1* ( 1+ 0.000542159)
1* ( 1+ 0.000542159) * ( 1+ -0.00162909400) and so on 

列最终索引我使用

以xls计算
(EXP(SUM(LOG(NULLIF(t2.InterMediateIndex + 1, 0))))

我尝试使用自右连接和$r.MyItems.Items[4].OnlineStatus = 0/1)但它总是乘以1而不是先前计算的索引

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

这里的一种方法被称为" Quirky Update"您可以在Jeff Moden的这篇文章中详细了解: http://www.sqlservercentral.com/articles/T-SQL/68467/和Itzik Ben-Gan的书: https://www.amazon.com/Microsoft-High-Performance-Functions-Developer-Reference/dp/0735658366

-- sample data
IF OBJECT_ID('tempdb..#yourtable') IS NOT NULL DROP TABLE #yourtable;
CREATE TABLE #yourtable
(
  someID    int identity primary key,
  [date]    date NOT NULL,
  [Returns] decimal(10,9) NOT NULL,
  [Final Return Index] decimal(10,9) NULL
);

INSERT #yourtable([date], [Returns])
VALUES
('11/1/2016', 0.000542159 ),
('11/2/2016',-0.001629094 ),
('11/3/2016', 0.000568779 ),
('11/4/2016',-0.001246407 ),
('11/7/2016', 0.000795611 ),
('11/8/2016', 0.000663507 ),
('11/9/2016',-0.000254819 );
GO

-- Review what you have
SELECT * FROM #yourtable;

-- The solution
DECLARE @runningTotal decimal(10,9) = 1;

UPDATE #yourtable
SET @runningTotal = [Final Return Index] = @runningTotal+[Returns]
FROM #yourtable WITH (TABLOCKX)
OPTION (MAXDOP 1);

SELECT [date], [Returns], [Final Return Index]
FROM #yourtable;

结果:

date         Returns         Final Return Index
----------   --------------- --------------------
2016-11-01   0.000542159     1.000542159
2016-11-02   -0.001629094    0.998913065
2016-11-03   0.000568779     0.999481844
2016-11-04   -0.001246407    0.998235437
2016-11-07   0.000795611     0.999031048
2016-11-08   0.000663507     0.999694555
2016-11-09   -0.000254819    0.999439736

我不知道您在SQL或Excel中使用的数据类型,但是您必须解决这个问题以获得更精确的结果。注意"规则"在Jeff Moden的上述文章的最后。

或者,如果您运行的是SQL Server 2012+,则可以使用所谓的"窗口聚合函数"像这样:

-- sample data
IF OBJECT_ID('tempdb..#yourtable') IS NOT NULL DROP TABLE #yourtable;
CREATE TABLE #yourtable
(
  [date]    date NOT NULL,
  [Returns] decimal(10,9) NOT NULL
);

INSERT #yourtable([date], [Returns])
VALUES
('11/1/2016', 0.000542159 ),
('11/2/2016',-0.001629094 ),
('11/3/2016', 0.000568779 ),
('11/4/2016',-0.001246407 ),
('11/7/2016', 0.000795611 ),
('11/8/2016', 0.000663507 ),
('11/9/2016',-0.000254819 );

-- Solution:
SELECT 
  [date], 
  [Returns], 
  [Final Return Index] = 1 + SUM([Returns]) OVER (PARTITION BY (SELECT NULL) ORDER BY date)
FROM #yourtable;

结果与上述相同。

答案 1 :(得分:1)

只是为了好玩,这种方法会生成并执行一些动态SQL。

Declare @YourTable table (Date date,Returns decimal(18,9))
Insert Into @YourTable values
('11/1/2016',  0.000542159),
('11/2/2016', -0.001629094),
('11/3/2016',  0.000568779),
('11/4/2016', -0.001246407),
('11/7/2016',  0.000795611),
('11/8/2016',  0.000663507),
('11/9/2016', -0.000254819)

Declare @SQL varchar(max) = '>>>'
Select @SQL = @SQL+String
 From (
        Select String=concat(',(|',Date,'|,',Returns,',',Stuff((Select '*' + cast(1.0+Returns as varchar(25)) 
                                                                 From  @YourTable 
                                                                 Where Date<=A.Date 
                                                                 For XML Path ('')),1,1,'') ,')')
        From   @YourTable A
      ) A
Select @SQL = 'Select * From (values '+replace(replace(@SQL,'|',''''),'>>>,','')+') A(Date,Returns,Final)'
Exec(@SQL)

<强>返回

Date         Returns        Final
2016-11-01   0.000542159    1.000542159
2016-11-02  -0.001629094    0.998912182
2016-11-03   0.000568779    0.999480342
2016-11-04  -0.001246407    0.998234583
2016-11-07   0.000795611    0.999028789
2016-11-08   0.000663507    0.999691652
2016-11-09  -0.000254819    0.999436911

生成的SQL将如下所示

Select Date,Returns,Final=cast(Final as decimal(18,9)) 
 From (values ('2016-11-01', 0.000542159,1.000542159)
             ,('2016-11-02',-0.001629094,0.998370906*1.000542159)
             ,('2016-11-03', 0.000568779,0.998370906*1.000542159*1.000568779)
             ,('2016-11-04',-0.001246407,0.998370906*0.998753593*1.000542159*1.000568779)
             ,('2016-11-07', 0.000795611,0.998370906*0.998753593*1.000542159*1.000568779*1.000795611)
             ,('2016-11-08', 0.000663507,0.998370906*0.998753593*1.000542159*1.000568779*1.000663507*1.000795611)
             ,('2016-11-09',-0.000254819,0.998370906*0.998753593*0.999745181*1.000542159*1.000568779*1.000663507*1.000795611)
      ) A(Date,Returns,Final)