2012-10-19 34 views
1

給定起始值@pStartingValue和包含rorDateror的表格是什麼使用TSQL在每個日期獲取NAV的最有效方式?如何在SQL中將回報率累計爲淨資產值?

這在數學上微不足道,而且代碼簡單。目前我有一個天真的SQL實現依賴於遊標。

第一次約會時,淨資產值已@pStartingValue * ROR
在隨後每次約會,這是先前計算的資產淨值* ROR 它@pStartingValue *每以前ROR

你將如何有效地做到這一點只在MSSQL2005 +?

DECLARE @rorDate DATE 
DECLARE @getDate CURSOR 
DECLARE @lastNAV as DECIMAL(19,7) 
DECLARE @datedRoR as float 
DECLARE @NAVTotals TABLE 
(
    NAV DECIMAL(19,7), 
    navDate DATE 
) 


SET @lastNAV = 100 

SET @getDate = CURSOR FOR 
    SELECT 
     p.[DATE] 
    FROM 
     performance p 
    ORDER BY 
     p.[DATE] 

OPEN @getDate 
FETCH NEXT 
FROM @getDate INTO @rorDate 
WHILE @@FETCH_STATUS = 0 
BEGIN 

SELECT 
    @datedRoR = b.finalNetReturn 
FROM 
    performance b 
WHERE 
    b.date = @rorDate 

INSERT INTO @NAVTotals (NAV, navDate) 
    VALUES (@lastNAV * (1 + @datedRoR), @rorDate) 

SELECT 
    @lastNAV = c.NAV 
FROM 
    @NAVTotals c 
WHERE 
    c.navDate = @rorDate 


FETCH NEXT 
FROM @getDate INTO @rorDate 
END 
CLOSE @getDate 
DEALLOCATE @getDate 

select * from @NAVTotals 
+2

向我們展示您的光標方法,並且您可能會獲得與預期輸出相匹配的更好結果。 – RThomas

+0

@RThomas我添加了我的遊標實現 – Matthew

回答

1

你必須做一些測試,看看性能有所提升,但是這是一種方式做同樣的事情,而不使用遊標。它沒有經過測試,所以你要確保測試它。我還將b.finalNetReturn作爲浮點數,如果它已經是浮點數,則可以移除該部分。

DECLARE @lastNAV as DECIMAL(19,7) 

SET @lastNAV = 100  

DECLARE @NAVTotals TABLE 
(
    NAV DECIMAL(19,7), 
    navDate DATE 
); 

INSERT INTO @NAVTotals (navDate) 
    SELECT [DATE] 
    FROM performance 
    ORDER BY [DATE] ASC; 

UPDATE NT 
SET @lastNAV = Nav = (@lastNAV * (1.0 + 
(Cast((SELECT b.finalNetReturn 
     FROM performance b 
     WHERE b.date = NT.navDate) AS FLOAT)))) 
FROM @NAVTotals NT; 

SELECT * FROM @NAVTotals ORDER BY navDate; 

通過降低lastNAV可變進可以同時更新的更新語句。它的作用類似於:

a = a + 1 

有一個example of this same approach here。包括一些比較該方法與其他方法(如遊標)效率的好數字。

+0

我沒有看到@lastNAV如何設置?這似乎不會起作用。 – Matthew

+0

對不起,我打字速度比我想象的要快。現在看看。我認爲這應該可行 - 這是我以前用於運行總體類型操作的一種方法。如果我誤解了你想做的事情,請告訴我。 – RThomas

+0

不執行,必須聲明標量變量@NAVTotals,你不能在子查詢中使用表引用作爲標量。 – Matthew

0

也許我沒有正確理解它,但你甚至不需要存儲過程來實現這一點。

SELECT p.[DATE] AS navDate 
    , @pStartingValue * PRODUCT(1 + b.finalNetReturn) AS NAV 
    FROM performance p 
INNER JOIN performance b 
    ON b.[DATE] <= p.[DATE] 
GROUP BY p.[DATE] 
ORDER BY p.[DATE] 

但是,有一些我不明白的「奇怪」。

  1. 怎麼沒有p。[DATE]的範圍限制?
  2. 「性能」表是否真的只有一項資產?
+0

您的查詢不起作用,它只是將起始值乘以每個ror,但不會累積它們。不,表格有多個資產,但我每次訪問它們一個,所以我可以根據需要追加'WHERE'子句。我只是從樣本中刪除它。 – Matthew

+0

你運行過嗎? PRODUCT是一個聚合函數。還要注意別名p或b。 –

+0

MSSQL中沒有'PRODUCT'聚合函數。 – Matthew