给定起始值@pStartingValue
以及包含rorDate
和ror
的表格,使用TSQL在每个日期获取资产净值的最有效方法是什么?
这在数学上是微不足道的,而且代码简单。我目前有一个天真的SQL实现,它依赖于游标。
在第一个日期,资产净值为@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
答案 0 :(得分: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变量放入update语句,您可以更新它们。它的工作方式类似于:
a = a + 1
有一个example of this same approach here。包括一些比较方法的效率与光标等其他方法的效率。
答案 1 :(得分: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]
然而,有一些我不理解的“诡计”。