尝试计算列的值,其中根据前一行的计算值计算该值。 (如下图所示)
其中列Z是计算列,作为X * Y的乘积,当没有前一行时,Y列的值应为1,否则该值应为先前的Z列值。
这可以使用Cursor实现,但尝试使用SQL Query查找它。
答案 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;