基于其他两列并使用 LAG 函数更新 Oracle 过程中的列

Updating a column in an Oracle procedure based on other two columns and using a LAG function

我正在尝试使用以下过程更新列,它使用 LAG 函数,因为结果是通过将先前值减去当前值来计算的,如下图所示,但是它就它用我根本不期望的值填充 col3 而言不起作用..

基本上我想要的是(用Excel来说明问题):

table.

中每个不同的名字我都想要这个
create or replace procedure proc1 as
  cursor cur is
    SELECT (col1 - LAG(col1,1) OVER (PARTITION BY name order by ID)) 
    FROM table1 
    for update;
    var_diff NUMBER;
begin
  open cur;
  loop
    fetch cur into var_diff;
    exit when cur%NOTFOUND;
    update table1 set col3=var_diff where current of cur;
  end loop;
  close cur;
end proc1;
/

exec proc1;
commit;

例如,我知道上面使用的 SQL 语句有效:

SELECT col1, 
       LAG(col1,1) OVER (PARTITION BY name order by ID), 
       (col1 - LAG(col1,1) OVER (PARTITION BY name order by ID)) 
FROM table1;

但是我无法使程序正常工作。

我觉得这可以通过 SQL 轻松完成。如果可能,我们 should/must 总是尝试通过 SQL 方法解决问题,然后在需要时寻找 PLSQL 选项。这个需求可以通过 MERGE 或简单的 UPDATE 语句轻松完成。我已经说明了 PLSQL ND sql 两种方式。希望这有帮助。

--SQL Way better then PLSQL way
merge INTO TABLE1 tab USING
(SELECT (COL1 - LAG(COL1,1) over (partition BY name order by id)) COL1
FROM TABLE1
)a ON (TAB.COL1 = a.COL1)
WHEN matched THEN
  UPDATE SET COL3 = a.COL1 WHERE col1 = a.col1;

--PLSQL way but will be slow as we are doing it row-row aka slow-by-slow provcessing
CREATE OR REPLACE
PROCEDURE proc1
AS
BEGIN
  for I        in
  (SELECT (COL1 - LAG(COL1,1) over (partition BY name order by id)) col3,col1
  FROM table1
  )
  LOOP
    UPDATE table1 SET col3=i.col3 where col1 = i.col1;
  END LOOP;
END proc1;

最后,听从别人的建议,SQL这句话对我有用:

MERGE INTO TABLE1 tab 
    USING (SELECT ID,(NVL(COL1,0) - NVL(LAG(NVL(COL1,0),1) OVER (PARTITION BY NAME order by ID),0)) VAL FROM TABLE1) a 
    ON (tab.ID = a.ID)
    WHEN matched THEN
      UPDATE SET tab.COL3 = a.VAL;