在SQL中,如何将回报率汇总为资产净值?
给定起始值在SQL中,如何将回报率汇总为资产净值?,sql,sql-server,tsql,stored-procedures,calculated-columns,Sql,Sql Server,Tsql,Stored Procedures,Calculated Columns,给定起始值@pStartingValue和包含rorDate和ror的表格,仅使用TSQL获取每个日期的NAV最有效的方法是什么 这在数学上很简单,代码也很简单。我目前有一个简单的SQL实现,它依赖于游标 在第一个日期,资产净值为@pStartingValue*ror 在随后的每个日期,它是先前计算的nav*ror或它是@pStartingValue*之前的每个ror 仅在MSSQL2005+中,您如何高效地执行此操作 DECLARE @rorDate DATE DECLARE @getDate
@pStartingValue
和包含rorDate
和ror
的表格,仅使用TSQL获取每个日期的NAV最有效的方法是什么
这在数学上很简单,代码也很简单。我目前有一个简单的SQL实现,它依赖于游标
在第一个日期,资产净值为@pStartingValue*ror在随后的每个日期,它是先前计算的nav*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
您必须进行一些测试,看看性能是否有所提高,但这是一种不用光标即可完成相同任务的方法。它未经测试,因此您需要确保对其进行测试。我还将
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
有一个问题。包括一些比较该方法与其他方法(如游标)效率的好数字。您必须进行一些测试,看看性能是否有所提高,但这是一种不用游标即可完成相同任务的方法。它未经测试,因此您需要确保对其进行测试。我还将
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
有一个问题。包括一些比较该方法与其他方法(如游标)效率的好数字。也许我没有正确理解它,但您甚至不需要存储过程来实现这一点
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]
选择p.[DATE]作为导航日期
,@pStartingValue*产品(1+b.finalNetReturn)作为资产净值
从性能p
内部连接性能b
在b.[DATE]上,也许我没有正确理解它,但您甚至不需要存储过程来实现这一点
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]
选择p.[DATE]作为导航日期
,@pStartingValue*产品(1+b.finalNetReturn)作为资产净值
从性能p
内部连接性能b
b.[日期]向我们展示您的光标方法和可能获得与预期输出相匹配的更好结果的方法。@r我添加了光标实现,向我们展示了您的光标方法和可能获得与预期输出相匹配的更好结果的方法。@r我添加了光标实现,我不知道如何设置@lastNAV?这好像不行。对不起,我打字比我想象的快。现在看看。我认为这应该行得通——这是我过去用于运行总类型操作的方法。如果我误解了您的尝试,请告诉我。如果不执行,则必须声明标量变量@NAVTotals,则不能在子查询中将表引用用作标量。您必须使用表别名,并且在更新时必须更加复杂。修复了答案(再次)。您的解决方案有效,但不适用于我的实际实现。我原以为我可以简化它,将其发布到这里,但实际上,我在表中有多个资产(由assetID关联)到“StartingAssetValue”表。不过,我确实认为你回答了这个问题!我不知道@lastNAV是怎么设置的?这好像不行。对不起,我打字比我想象的快。现在看看。我认为这应该行得通——这是我过去用于运行总类型操作的方法。如果我误解了您的尝试,请告诉我。如果不执行,则必须声明标量变量@NAVTotals,则不能在子查询中将表引用用作标量。您必须使用表别名,并且在更新时必须更加复杂。修复了答案(再次)。您的解决方案有效,但不适用于我的实际实现。我原以为我可以简化它,将其发布到这里,但实际上,我在表中有多个资产(由assetID关联)到“StartingAssetValue”表。不过,我确实认为你回答了这个问题!您的查询将不起作用,它只是将startingvalue乘以每个ror,但不会累加它们。不,表有多个资产,但我一次访问一个资产,以便根据需要附加“WHERE”子句。我刚把它从样本中删除了,你运行了吗?积是一个聚合函数。还要注意别名p或b。MSSQL中没有PRODUCT
aggregate函数。您的查询将不起作用,它只是将startingvalue乘以每个ror,但不会累加它们。不,表有多个资产,但我一次访问一个资产,以便根据需要附加“WHERE”子句。我刚把它从样本中删除了,你运行了吗?积是一个聚合函数。还要注意别名p或b。MSSQL中没有PRODUCT
aggregate函数。