如何在SQL中计算行上的累计和

时间:2018-08-08 16:30:15

标签: sql sql-server sql-server-2008

我有以下SQL表:

StockID  Flow   Stock
1        +      2
1        -      3
1        +      8

我还有一张桌子:

ID   InStock
1    22
2    51
3    92

我要选择第二个表22的第一个值,并根据登录情况,用Stock从第一个表的值StockID = ID累加或减去。流量列。然后从该解决方案中添加/减去列Stock中的值。

这应该出现在新列Sol中:

ID    Flow   Stock    Sol
1      +      2        24    (22+2)
2      -      3        21    (24-3)
3      +      8        29    (21+8)

您有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您需要在第一个表中添加某种排序列。否则,这是没有意义的。我决定添加额外的列seq,以达到此目的。

因此,具有以下数据:

create table flow (
  stockid int,
  seq int,
  flow char(1),
  stock int
);

insert into flow (stockid, seq, flow, stock) values (1, 10, '+', 2);
insert into flow (stockid, seq, flow, stock) values (1, 11, '-', 3);
insert into flow (stockid, seq, flow, stock) values (1, 12, '+', 8);

create table stock (
  id int,
  instock int
);

insert into stock (id, instock) values (1, 22);
insert into stock (id, instock) values (2, 51);
insert into stock (id, instock) values (3, 92);

查询为:

select s.id, f.seq, f.flow, f.stock,
    s.instock + 
      sum(case when f.flow = '+' then 1 else -1 end * f.stock)
      over(partition by s.id order by f.seq) as sol
  from stock s
  left join flow f on f.stockid = s.id;

结果:

id  seq     flow    stock   sol          
--  ------  ------  ------  ------
1   10      +       2       24    
1   11      -       3       21    
1   12      +       8       29    
2   <null>  <null>  <null>  <null>
3   <null>  <null>  <null>  <null>

答案 1 :(得分:0)

在SQL Server 2008中,您受困于apply来计算累积总和:

select t1.*, tt1.stock + t2.instock
from t1 cross apply
     (select sum(case when flow = '+' then tt1.sock else - tt1.stock end) as stock
      from t1 tt1
      where tt1.id <= t1.id
     )  tt1 cross join
     (select top (1) t2.*
      from t2
      order by id
     ) t2;