【发布时间】:2017-09-12 12:02:50
【问题描述】:
我有一个数据集,我需要计算一个值,该值的每一行取决于同一列的前一行中的值。或者当没有上一行时最初为 1。我需要在不同的分区上执行此操作。
公式如下所示:factor = (前一个因子,如果不存在则为 1) * (1 + div / nav) 这需要通过 Inst_id 进行分区。
我宁愿避免使用光标。也许 cte 带有递归 - 但我无法理解它 - 或其他方式?
我知道这段代码不起作用,因为我无法引用同一列,但这是显示我正在尝试做的事情的另一种方式:
SELECT Dato, Inst_id, nav, div
, (1 + div / nav ) * ISNULL(LAG(factor, 1) OVER (PARTITION BY Inst_id ORDER BY Date), 1) AS factor
FROM @tmp
因此,我需要使用我的测试数据在下面的因子列中获得这些结果。 请忽略舍入问题,因为我是在 Excel 中计算的:
date Inst_id nav div factor
11-04-2012 16 57.5700 5.7500 1.09987841
19-04-2013 16 102.8600 10.2500 1.20948130
29-04-2014 16 65.9300 16.7500 1.51675890
08-04-2013 29 111.2736 17.2500 1.15502333
10-04-2014 29 101.9650 16.3000 1.33966395
15-04-2015 29 109.5400 7.5000 1.43138825
27-04-2016 29 94.2500 0.4000 1.43746311
15-04-2015 34 159.1300 11.4000 1.07163954
27-04-2016 34 124.6100 17.6000 1.22299863
26-04-2017 34 139.7900 9.2000 1.30348784
01-04-2016 38 99.4600 0.1000 1.00100543
26-04-2017 38 102.9200 2.1000 1.02143014
测试数据:
DECLARE @tmp TABLE(Dato DATE, Inst_id INT, nav DECIMAL(26,19), div DECIMAL(26,19), factor DECIMAL(26,19))
INSERT INTO @tmp (Dato, Inst_id, nav, div) VALUES
('2012-04-11', 16, 57.57, 5.75),
('2013-04-19', 16, 102.86, 10.25),
('2014-04-29', 16, 65.93, 16.75),
('2013-04-08', 29, 111.273577, 17.25),
('2014-04-10', 29, 101.964994, 16.3),
('2015-04-15', 29, 109.54, 7.5),
('2016-04-27', 29, 94.25, 0.4),
('2015-04-15', 34, 159.13, 11.4),
('2016-04-27', 34, 124.61, 17.6),
('2017-04-26', 34, 139.79, 9.2)
我使用的是 Microsoft SQL Server Enterprise 2016(并使用 SSMS 2016)。
【问题讨论】:
标签: sql-server tsql recursion sql-server-2016 multiplication