Oracle PL / SQL:访问当前行中的上一行计算值

时间:2018-05-30 09:08:49

标签: sql oracle

尝试计算列的值,其中根据前一行的计算值计算该值。 (如下图所示)

Image

其中列Z是计算列,作为X * Y的乘积,当没有前一行时,Y列的值应为1,否则该值应为先前的Z列值。

这可以使用Cursor实现,但尝试使用SQL Query查找它。

2 个答案:

答案 0 :(得分:3)

看起来你要做的就是在所有行上进行累积乘法。

你可以通过使用数学技巧(又名自然日志和指数)来做到这一点,你可以在这里使用x值的自然对数的累积和,然后使用指数函数将结果转换回整数:

WITH your_table AS (SELECT 'ABC' a, 12 x FROM dual UNION ALL
                    SELECT 'BBC' a, 20 x FROM dual UNION ALL
                    SELECT 'CBC' a, 10 x FROM dual UNION ALL
                    SELECT 'XYZ' a, 5 x FROM dual)
 SELECT a,
       x,
       LAG(z, 1, 1) OVER (ORDER BY a) y,
       z
FROM   (SELECT a,
               x,
               EXP(SUM(LN(x)) OVER (ORDER BY a)) z
        FROM   your_table);

A            X          Y          Z
--- ---------- ---------- ----------
ABC         12          1         12
BBC         20         12        240
CBC         10        240       2400
XYZ          5       2400      12000

然后,如果您需要查看前一个值(也就是您的y列),您可以在计算列周围抛出一个滞后()来查找上一行的值(如果没有前一行,则指定1到它)。

ETA:如果您已经有一个包含信息的表,那么添加一个新行就可以找到最后一行并使用它来乘以新的x值。例如。:

insert into your_table (a, x, y, z)
select 'YMX' a, 2 x, z as new_y, 2*z as new_z
from   (select z,
               row_number() over (order by a desc) rn
        from   your_table)
where  rn = 1;

这会找到最新的行(我们使用row_number()分析函数来标记行,从最新的值(属于最后一行)开始),然后我们可以使用该行的z值来查找新行y值,并将其乘以新的x值以找到新的z值。

然后你只需要插入这一行。

答案 1 :(得分:0)

我认为最简单的方法根本不使用lag()或子查询。一种方法是简单划分:

SELECT a, x, y
       ( EXP(SUM(LN(x * y)) OVER (ORDER BY a)) ) / (x * y) as z
FROM t;

或者使用带coalesce()的窗口子句:

SELECT a, x, y
       COALESCE( EXP(SUM(LN(x * y)) OVER (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)), 1 ) as z
FROM t;