在SQL中查看累积的自引用计算

时间:2018-05-10 17:56:52

标签: mysql sql variables recursion

我甚至不确定该怎么称呼我要做的事情。我需要一个在前一行累积自己计算总数的列。这是我需要的输出的简化示例(d是我需要帮助的列):

a   b   c   d   e
1   36  6   36  6
2   0   5   30  6
3   0   4   24  6
4   22  10  40  4
5   0   9   36  4
6   0   8   32  4

a是自动编号列

b是用户输入的列

c是一个通常倒数一列的列,但偶尔会添加其他值

d等于:d + b的前一行 - e的前一行

e等于d / c

如果我解释为什么需要这个,这可能会有所帮助。我正在努力模拟利率冲击对银行机构的影响(通常称为压力测试)。 b是代表利率冲击的一些影响的专栏(例如:贷款数量的百分比变化)。 c是一列,表示市场在没有任何进一步的利率冲击的情况下恢复正常之前的月数。 d表示该时间段对贷款的影响,e表示d返回零的比率。

这是我到目前为止所尝试的以及为什么它不起作用:

SET var := 0;

SELECT var := var + b - var/c AS d

这将是我首选的解决方案,但我正在创建一个视图,并且不允许视图引用用户创建的变量。它必须是一个视图,因为我需要在其他查询和视图中引用它。

SELECT (lag(d,1,0) OVER (ORDER BY a)) + b - (lag(e,1,0) OVER (ORDER BY a)) AS d

这不起作用,因为尚未定义d。我只是得到一个d不是列的错误。

SELECT
     ((SELECT sum(temp.b)
     FROM table as temp
     WHERE temp.a <= a)
     /(SELECT sum(temp2.c)
     FROM table as temp2
     WHERE temp2.a = a))

这不起作用,因为我需要除以d的减少值,而不仅仅是b的总和。

3 个答案:

答案 0 :(得分:0)

dbc之间差异的累积总和。这将表示为:

select a, b, c,
       sum(b - c) over (order by a) as d,
       d / sum(b - c) over (order by a) as e
from t;

我正在使用窗口函数,即使问题标记为MySQL。 MySQL从版本8.0开始只支持它们。

答案 1 :(得分:0)

我不确定结果在VIEW中的稳定程度,但您可以使用会话变量。

SELECT a, b, c, @d := @d + b - @e AS d, @e := @d / c AS e
FROM t
   , (SELECT @d := 0 AS initD, @e := 0 AS initE) As init
ORDER BY a;

另外,请记住,这是一种跨越观察到的行为,而不是实际保证;因为MySQL没有正式保证从左到右评估选择表达式。

答案 2 :(得分:0)

我用纯粹的蛮力解决了这个问题。我创建了一个永久表,然后我创建了一个触发器,删除表的所有行,然后使用变量解决方案重新创建表。因此,只要基础数据发生变化,MySQL就会使用最新信息自动更新表格。该表就像一个视图,它实时更新,但是是一个永久表。

不幸的是,MySQL并没有为触发器提供FOR EVERY STATEMENT选项,这意味着我的代码会针对每一行更新而反复运行,所以如果我更新100行,我的表会被删除并重新创建100次。

仍在寻找更好的解决方案,但至少可行。