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

Used data from the previous record to calculate data of the current one

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

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

更新:

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

您要计算 运行 总数,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

试试这个:

 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  

试试吧:)

 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  

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

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

该请求有点不寻常,因为 SQL 集合处理倾向于关注集合而不是相对记录编号。因此,无法使用递归 CTE,因为没有简单的 parent/child 关系。但是,可以使用蛮力。

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;

我们的想法是获取第一行,它使用当前行的列进行计算,然后将其联合到后续行,这些行使用当前行和上一行的计算。

编辑 假设 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 行检索初始数量。

也许下面的内容与我对 的回复非常相似,但是除了使用给定样本数据进行测试的结果外,我几乎没有对这个回复进行任何评论 [加上用于直观表达的列等同于预期输出]来验证:

设置:

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  ********