2017-03-10 79 views
1

我想根據可用的回報計算價格指數。根據SQL中的回報計算價格指數

這裏是一個原始數據

+-----------+--------------+--------------------+ 
| Date | Returns | Final Return Index | 
+-----------+--------------+--------------------+ 
| 11/1/2016 | 0.000542159 |  1.000542159 | 
| 11/2/2016 | -0.001629094 |  0.998912181 | 
| 11/3/2016 | 0.000568779 |  0.999480341 | 
| 11/4/2016 | -0.001246407 |  0.998234581 | 
| 11/7/2016 | 0.000795611 |  0.999028788 | 
| 11/8/2016 | 0.000663507 |  0.999691651 | 
| 11/9/2016 | -0.000254819 |   0.99943691 | 
+-----------+--------------+--------------------+ 

柱最終索引我XLS已經計算出使用

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

我試圖用自決權JOIN和(EXP(SUM(LOG(NULLIF(t2.InterMediateIndex + 1, 0))))),但它總是與1,而不是以前的相乘計算指數

任何幫助,高度讚賞。

+1

所以你想要運行總計? – scsimon

+0

更正同一表中不同帳戶組合的運行總額。 – user1143726

回答

1

這裏有一個方法被稱爲「古怪的更新」 method.You能本文由傑夫MODEN在閱讀更多關於: http://www.sqlservercentral.com/articles/T-SQL/68467/和伊茨克奔甘的書: 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; 

結果將與上面相同。

+0

非常感謝您的建議。如果你能幫忙,我還有一個問題。如果在同一日期時間系列中有兩個不同的帳戶,那麼我如何應用group by,因爲我無法將回報添加到group by子句。 – user1143726

+0

我得到了我將通過帳戶進行分區的解決方案。再次感謝。 – user1143726

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) 
+0

感謝您的解決方案。我通過解決方案將分區應用於帳戶 – user1143726

+0

@ user1143726以運行總計和分組。如果它在原始請求中,它將很容易併入。也就是說,我明白要求一個清晰而簡潔的問題,而不會讓問題變得過於詳細。 –