基于其他两列并使用 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;
我正在尝试使用以下过程更新列,它使用 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;