Oracle sql 数学计算使用当前和前一个行值

Posted

技术标签:

【中文标题】Oracle sql 数学计算使用当前和前一个行值【英文标题】:Oracle sql math calculation using current and previous row values 【发布时间】:2016-12-20 07:32:10 【问题描述】:

我有下表:

ID  A   B   C
1   1   23  22
2   2   19  20
3   5   18  15
4   3   12  12

A 列和 B 列是常数。我想使用以下公式计算 C 列:

第一行

 C = B - A

之后

 C = previous(C) - A

我只想使用 oracle SQL 来实现这一点。

【问题讨论】:

行序是什么?因为数据库可以按任何顺序检索行。 @GurwinderSingh 我相信ID 是一个安全的假设。 我添加了一个 ID 列,用于行顺序 第一行你想得到什么?没有“以前的”。 @Boneist 列 ID、A、B 是输入,C 列是我想要得到的 【参考方案1】:

如果你把你的数据的形式放在

    A    B       C
   a1   b1   b1 - a1     == b1 - a1
   a2   b2   c1 - a2     == b1 - a1 - a2 
   a3   b3   c2 - a3     == b1 - a1 - a2 - a3
   a4   b4   c3 - a4     == b1 - a1 - a2 - a3 - a4
   ...
   an   bn   cn-1 - an   == b1 - a1 - a2 - ... - an

您可以在分析函数中轻松找到解决方案,例如

select A,
       B, 
       first_value(B) over(order by id) - sum(A) over (order by id) C
  from myTable   

请检查实际订单(我已输入order by id

【讨论】:

老鼠们,我慢了 16 秒! *;-)我想是(order by id) @Dmitry 真棒 @Dmitry - 感谢您的明确细分,我正在为类似的事情苦苦挣扎,您的解释为我钉上了钉子。我能够使用逻辑来分解我的公式并让它发挥作用。【参考方案2】:

看看 Oracle 分析函数。 https://oracle-base.com/articles/misc/lag-lead-analytic-functions

在您的情况下,您正在尝试计算列 C,它是派生列,并且此类派生列的先前值不能在 LAG 函数的公式中直接引用。

因此,诀窍是使用 C 列的定义来派生每一行。在第 3 行,C 的值应该是 C@row2 - A@row3 = C@row1 - (A@row3 + A@row2) = C@row1 + A@row1 - sum(a @ row1,2,3),这不是 sql 语法,我只是想解释一下算法

当您尝试使用 Oracle sql 编写相同的内容时,查询应如下所示

SELECT ID,A,B, (LAG(C_+A,RN-1,0) OVER (ORDER BY ID)) - SUM(A) OVER (ORDER BY ID) as c FROM(
  SELECT ID, A, B, B-A AS C_, ROWNUM RN FROM TEST
)

假设表名是TEST,列名是ID, A, B

结果看起来像

ID  A   B   C
1   1   23  22
2   2   19  20
3   5   18  15
4   3   12  12

【讨论】:

以上是关于Oracle sql 数学计算使用当前和前一个行值的主要内容,如果未能解决你的问题,请参考以下文章

pandas使用pct_change函数计算数据列的百分比变化:计算当前元素和前一个元素之间的百分比变化(包含NaN值的情况以及数据填充方法)

计算前几行中大于当前行值的值

使用滞后函数访问当前行值

pandas使用pct_change计算数据列的百分比变化环比变化率:计算当前元素和前一个元素之间的百分比变化使用style函数指定format的格式:百分比缺失值替换用颜色标注极大值和极小值

Hive 分析函数lead、lag实例应用

如果 Oracle 中存在行值,则使用随机值更新行