使用上一条记录中的数据来计算当前记录的数据

时间:2016-09-25 09:40:43

标签: sql db2 ibm-midrange

AS400的LAG和LEAD语法是什么? 我正在尝试根据以前的记录对当前记录进行一些计算?

例如: 我需要根据前一个记录计算每个记录的工作中心数量。

enter image description here

更新

正如我在示例中所描述的那样,重要的是计算将基于前一行,而不是基于所有先前行的总和。我刚刚给出了一个非常优化的我的需求示例,但实际上减去所有以前记录的SUM并没有帮助我。有没有办法只订阅以前的记录?

5 个答案:

答案 0 :(得分:4)

您正在考虑计算一个总计,LAGLEAD无法帮助您完成。计算运行总计的一种方法是使用相关子查询:

SELECT t1.*,
       t1.total_quantity - (SELECT SUM(t2.scrap_quantity)
                            FROM yourTable t2
                            WHERE t2.work_center <= t1.work_center) AS work_center_quantity
FROM yourTable t1
ORDER BY t1.work_center

答案 1 :(得分:2)

首先,使用平台的正确名称,您将更有可能找到当前的参考资料。 IBM i文档位于Knowledge Center

其次,有三个DB2系列。 IBM i系列还没有LEAD和LAG。 (其他系列是LUW(Linux,Unix,Windows)和DB2 for z - 大型机)。

请求有点不寻常,因为SQL集处理往往集中在集而不是相对记录号上。因此,不能使用递归CTE,因为没有简单的父/子关系。但是,可以施加蛮力。

create table so (
  WorkCenter char(5),
  TotalQuantity decimal(7, 0),
  ScrapQuantity decimal(7, 0),
  WorkCenterQuantity decimal(7, 0)
  );

insert into so values ('A', 1000, 10, 990);
insert into so values ('B', 1000, 5, 985);
insert into so values ('C', 1000, 12, 973);
insert into so values ('D', 1000, 1, 972);

select 1 as level, WorkCenter, TotalQuantity, ScrapQuantity, WorkCenterQuantity, TotalQuantity - ScrapQuantity as newQUantity
from so
where rrn(so) = 1
 union all
select rrn(o) as level, o.WorkCenter, o.TotalQuantity, o.ScrapQuantity, o.WorkCenterQuantity, 
  (select i.WorkCenterQuantity
   from so i
   where rrn(i) = rrn(o) - 1) - o.ScrapQuantity as NewWorkCenterQuantity
from so o
where rrn(o) > 1
order by 1;

我们的想法是获取第一行,该行使用当前行的列进行计算,将UNION计算为后续行,后者使用当前行和上一行进行计算。

编辑假设WorkCenterQuantity为零。在计算中使用@Tim的运行总计。

update so
set WorkCenterQuantity = 0;

update so u
set WorkCenterQuantity = (
  select NewWorkCenterQuantity 
  from 
    (select 1 as level, WorkCenter, TotalQuantity, ScrapQuantity, WorkCenterQuantity, TotalQuantity - ScrapQuantity as NewWorkCenterQuantity
     from so
     where rrn(so) = 1 
      union all
     select rrn(o) as level, o.WorkCenter, o.TotalQuantity, o.ScrapQuantity, o.WorkCenterQuantity, 
       (select TotalQuantity
        from so
        where rrn(so) = 1) 
         - 
       (select sum(i.ScrapQuantity)
        from so i
        where rrn(i) <= rrn(o)) as NewWorkCenterQuantity
     from so o
     where rrn(o) > 1
     ) x 
  where u.WorkCenter = x.WorkCenter)
;

我们的想法是使用行n + 1的运行总计执行计算,但是从第1行检索初始数量。

答案 2 :(得分:1)

也许以下,与我对DB2 recursive UDF Table的回复非常接近,但是除了使用给定样本数据进行测试的结果之外,我几乎不做任何回顾[加上一个用于直观表达等效性的列预期输出]验证:

设定:

set current schema <whatever>
create table wc
( work_center    for wc       char     
, total_quantity for tq       dec      
, scrap_quantity for sq       dec      
, vfy_quantity   for vq       dec
) 
;
insert into  wc       values     
  ( 'A' ,   1000,     10,   990 )
, ( 'B' ,   1000,      5,   985 )
, ( 'C' ,   1000,     12,   973 )
, ( 'D' ,   1000,      1,   972 )
;

查询和结果:

with
  ordRows (rn, wc, tq, sq, vq) as
   ( select row_number() over(order by wc) as rn
          ,    wc, tq, sq, vq 
     from wc
   )    
, subRows (rn, wc, tq, sq, vq, cq /* calc qty */) as
   ( select rn, wc, tq, sq, vq
          , ( tq - sq )
     from ordRows
     where rn = 1
   union all
     select b.rn, b.wc, b.tq, b.sq, b.vq        
          , ( a.cq - b.sq )
     from subRows a
     join ordRows b
       on a.rn = ( b.rn - 1 )
   )
select dec(rn, 5) as rn, wc, tq, sq
     , vq, ' = ' as eq, cq
from subrows
; -- likeness of report from above query:
....+....1....+....2....+....3....+....4....+....5....+
    RN   WC      TQ       SQ       VQ   EQ          CQ 
     1   A    1,000       10      990    =         990 
     2   B    1,000        5      985    =         985 
     3   C    1,000       12      973    =         973 
     4   D    1,000        1      972    =         972 
********  End of data  ********                        

答案 3 :(得分:0)

试试这个:

 with tmp as (
 select t.*, rownumber() over(order by work_center  ) as rang
 from t)
 select f1.*, 
 ifnull(f2.work_center  , f1.total_quantity ) - f1.scrap_quantity 
 AS work_center_quantity 
 from tmp f1 left outer join tmp f2
 on f1.rang-1=f2.rang  

答案 4 :(得分:0)

尝试一下:)

 with tmp as (
 select t.*, rownumber() over(order by work_center  ) as rang
 from t)
 select f1.*, 
 f1.total_quantity - f3.sum_scrap_quantity    
 AS work_center_quantity 
 from tmp f1 
 inner join lateral
 (
  select sum(f2.scrap_quantity ) sum_scrap_quantity     tmp f2
  where f2.rang<=f1.rang
  ) f3 on 1=1