基于乘以前一行列计算结果

时间:2018-04-13 20:36:53

标签: sql oracle

我花了一些时间来找出使用滞后功能和最大功能的解决方案。但是当操作是sum或diff而不是乘法时,这种方法很好。

以下是原始表格:

    ArrayList<Object> list = new ArrayList<>();
    Random rand = new Random();

    for(int i = 0; i < 5; i++){
        list.add(new Object(rand.nextInt(50) + 1, rand.nextInt(50) + 1));
    }

    for(int i = 0; i < 5; i++){
        System.out.println(list.get(i).getOne());
    }

  }


public class Object {
  protected int one;
  protected int two;
public Object(int one, int two){
    this.one = one;
    this.two = two;
}

public int getOne() {
    return one;
}

public void setOne(int one) {
    this.one = one;
}

public int getTwo() {
    return two;
}

public void setTwo(int two) {
    this.two = two;
}

预期结果:

id  a   b       c
1   100 0.02    0
2       0.030   0
3       0.040   0
4       0.05    0

其中c是

id  a   b       c
1   100 0.02    102
2       0.030   105.06
3       0.040   109.2624
4       0.05    114.72552
id = 1的

异常:

case when id =1 then (a + a*b)
else prev row of c(Lag c) +prev row of c(Lag c) * b

id = 2:

c = (a + a*b)= 100 +100*0.02  = 102

id = 3:

c = 102 +102*0.03  = 105.06

使用滞后和最大函数尝试多个查询。能够在excel中轻松完成这项工作,而不像sql。

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

一种方法是递归CTE。另一种方法是实现PRODUCT()窗口函数。幸运的是,你可以使用一些算术来做到这一点。

因此,倍增因子是:

select t.*,
       exp(sum(log(1 + b)) over (order by id)) as factor
from t;

然后我们可以完成算术:

select t.*,
       max(a) over () * exp(sum(log(1 + b)) over (order by id)) as c
from t;

如上所述,这应该适用于Oracle和SQL Server,即原始标记。

Here是一个SQL小提琴。

答案 1 :(得分:0)

总和:

--drop table test

create table test(
  id numeric identity(1,1)
 ,a numeric
 ,b numeric
)

insert into test (a,b)values(100, 2)
insert into test (a,b)values(null,  3)
insert into test (a,b)values(null,  4)
insert into test (a,b)values(null,  5)

select id, a, b,
SUM( case when id = (select top 1 id from test) then (a+b) else b end) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as result
from test

enter image description here

乘法:

select id, a, b,
 exp(SUM( case when id = (select top 1 id from test) then log(a*b) else log(b) end) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) as result
from test

enter image description here