我有一个表格,该表格具有每月收益,如下所示。 我的目标是计算出10000美元的投资增长。 下面显示的investment_growth列是我手动计算的。对于第一个月,10000 *(1 + return / 100)将是第一个值。结果值将在公式中替换为下个月的回报,依此类推。
有人可以通过查询帮助我实现这一目标。
谢谢
[每月收益表-投资增长列是目标]
答案 0 :(得分:0)
您可以使用递归CTE来执行此操作,该CTE遍历您的表并可以引用以前计算的行。但是请注意,由于此行逐行循环,它可能会根据您的环境运行得相当慢:
declare @t table (FundName nvarchar(5),ReturnRate decimal(5,2), EndDate date);
insert into @t values('FundA',1.2,'20171231'),('FundA',-0.7,'20180131'),('FundA',1.3,'20180228'),('FundA',-2.3,'20180331'),('FundA',2.5,'20180430'),('FundA',1.9,'20180531'),('FundA',0.8,'20180630'),('FundB',1.1,'20171231'),('FundB',-0.4,'20180131'),('FundB',1.6,'20180228'),('FundB',-1.3,'20180331'),('FundB',2.0,'20180430'),('FundB',0.9,'20180531'),('FundB',0.8,'20180630');
declare @InitialInvestment int = 10000;
with rn as -- Apply a row number to each Fund, ordered by EndDate so the first row can be used as the anchor in the Recursive CTE below.
(
select FundName
,ReturnRate
,EndDate
,row_number() over (partition by FundName order by EndDate) as rn
from @t
)
,r as
(
select FundName -- Select just the first rows for each fund and calculate the Investment Growth
,ReturnRate
,EndDate
,rn
,cast(@InitialInvestment * (1 + (ReturnRate/100)) as decimal(20,10)) as InvestmentGrowth
from rn
where rn = 1
union all
select r.FundName -- Then row by row, fetch the next and calculate the Investment Growth by referencing the previous row in the dataset
,rn.ReturnRate
,rn.EndDate
,rn.rn
,cast(r.InvestmentGrowth * (1 + (rn.ReturnRate/100)) as decimal(20,10)) as InvestmentGrowth
from r
join rn
on r.FundName = rn.FundName
and r.rn = rn.rn-1
)
select FundName
,ReturnRate
,EndDate
,InvestmentGrowth
from r
order by FundName
,EndDate;
输出:
+----------+------------+------------+------------------+
| FundName | ReturnRate | EndDate | InvestmentGrowth |
+----------+------------+------------+------------------+
| FundA | 1.20 | 2017-12-31 | 10120.0000000000 |
| FundA | -0.70 | 2018-01-31 | 10049.1600000000 |
| FundA | 1.30 | 2018-02-28 | 10179.7990800000 |
| FundA | -2.30 | 2018-03-31 | 9945.6637011600 |
| FundA | 2.50 | 2018-04-30 | 10194.3052936890 |
| FundA | 1.90 | 2018-05-31 | 10387.9970942691 |
| FundA | 0.80 | 2018-06-30 | 10471.1010710233 |
| FundB | 1.10 | 2017-12-31 | 10110.0000000000 |
| FundB | -0.40 | 2018-01-31 | 10069.5600000000 |
| FundB | 1.60 | 2018-02-28 | 10230.6729600000 |
| FundB | -1.30 | 2018-03-31 | 10097.6742115200 |
| FundB | 2.00 | 2018-04-30 | 10299.6276957504 |
| FundB | 0.90 | 2018-05-31 | 10392.3243450122 |
| FundB | 0.80 | 2018-06-30 | 10475.4629397723 |
+----------+------------+------------+------------------+
答案 1 :(得分:0)
您可以使用“ Quirky Update”方法
一些测试数据
DECLARE @t TABLE ( [name] NVARCHAR(10), [return] DECIMAL(3,1), end_date DATE
, InvestmentGrowth DECIMAL(12,5) DEFAULT 0)
INSERT INTO @t
([name],[return],end_date)
VALUES
('FundA', 1.2, '20171231')
,('FundA', -0.7, '20180131')
,('FundA', 1.3, '20180228')
,('FundA', -2.3, '20180331')
投资始于10000
DECLARE @InvestmentAmount DECIMAL(12,5) = 10000
古怪的更新位
UPDATE @t
SET @InvestmentAmount = InvestmentGrowth = @InvestmentAmount * (1+([T].[return]/100))
FROM @t T;
name return end_date InvestmentGrowth
FundA 1.2 2017-12-31 10120.00000
FundA -0.7 2018-01-31 10049.16000
FundA 1.3 2018-02-28 10179.79908
FundA -2.3 2018-03-31 9945.66370