原语句如下(表名及字段名已改)
update mwm mwm set mwm.new_val = nvl((select sum(nvl(mws.pnl_qty, 0)) from mws mws where mws.o_id = mwm.o_id and mws.w_id = mwm.w_id and mws.a_num <= mwm.b_num), 0) where 1 = 1;
merge into mwm mwm using (select sum(pnl_qty) over(order by a_num) as pnl_qty, w_id, o_id, a_num from mws) mws on (mws.o_id = mwm.o_id and mws.w_id = mwm.w_id and mws.a_num = mwm.b_num) when matched then update set mwm.new_val = mws.pnl_qty;
merge into mwm mwm using (select sum(pnl_qty) over(partition by w_id, o_id order by a_num) as pnl_qty, w_id, o_id, a_num from mws) mws on (mws.o_id(+) = mwm.o_id and mws.w_id(+) = mwm.w_id and mws.a_num(+) = mwm.b_num) when matched then update set mwm.new_val = nvl(mws.pnl_qty, 0);
merge into mwm mwm using (select mwm.rowid as rid, sum(mws.pnl_qty) as pnl_qty from mwm mwm left join mws mws on (mws.o_id = mwm.o_id and mws.w_id = mwm.w_id and mws.a_num <= mwm.b_num) group by mwm.rowid) mws on (mws.rid = mwm.rowid) when matched then update set mwm.new_val = nvl(mws.pnl_qty, 0);改写后与update对比测试,这次数据终于对了,下次改写时一定要再小心些
如果看了上面描述还不清楚的话,那我们建个环境模拟说明下
首先建立环境
SQL> drop table emp1; Table dropped SQL> drop table emp2; Table dropped SQL> create table emp1 as select * from scott.emp; Table created SQL> create table emp2 as select * from scott.emp; Table created SQL> alter table emp1 add sal1 number(18,2); Table altered SQL> alter table emp1 add sal2 number(18,2); Table altered SQL> delete from emp2 where rownum <=2; 2 rows deleted第一个错误写法如下,有9条数据更新不对
SQL> update emp1 2 set emp1.sal1 = nvl((select sum(emp2.sal) 3 from emp2 4 where emp2.deptno = emp1.deptno 5 and emp2.empno <= emp1.empno), 6 0); 12 rows updated SQL> merge into emp1 2 using (select sum(emp2.sal) over(order by emp2.empno) as sal, empno, deptno 3 from emp2) emp2 4 on (emp2.empno(+) = emp1.empno and emp2.deptno(+) = emp1.deptno) 5 when matched then 6 update set emp1.sal2 = nvl(emp2.sal, 0); Done SQL> select count(*) from emp1 where sal1 <> sal2; COUNT(*) ---------- 9
SQL> merge into emp1 2 using (select sum(emp2.sal) over(partition by emp2.deptno order by emp2.empno) as sal, empno, deptno 3 from emp2) emp2 4 on (emp2.empno(+) = emp1.empno and emp2.deptno(+) = emp1.deptno) 5 when matched then 6 update set emp1.sal2 = nvl(emp2.sal, 0); Done SQL> select count(*) from emp1 where sal1 <> sal2; COUNT(*) ---------- 0
SQL> update emp2 set empno = empno - 1 where rownum <=5; 5 rows updated SQL> update emp1 2 set emp1.sal1 = nvl((select sum(emp2.sal) 3 from emp2 4 where emp2.deptno = emp1.deptno 5 and emp2.empno <= emp1.empno), 6 0); 12 rows updated SQL> merge into emp1 2 using (select sum(emp2.sal) over(partition by emp2.deptno order by emp2.empno) as sal, empno, deptno 3 from emp2) emp2 4 on (emp2.empno(+) = emp1.empno and emp2.deptno(+) = emp1.deptno) 5 when matched then 6 update set emp1.sal2 = nvl(emp2.sal, 0); Done SQL> select emp1.deptno as deptno1, emp1.empno as empno1, emp2.empno as empno2 2 from emp1, emp2 3 where emp1.sal1 <> emp1.sal2 4 and emp2.deptno = emp1.deptno 5 and emp2.empno <= emp1.empno 6 order by 1, 2, 3; DEPTNO1 EMPNO1 EMPNO2 ------- ------ ------ 10 7782 7781 20 7566 7565 30 7521 7520 30 7654 7520 30 7654 7653 30 7698 7520 30 7698 7653 30 7698 7697 8 rows selected
SQL> merge into emp1 2 using (select sum(emp2.sal) as sal, emp1.rowid as rid 3 from emp1 4 left join emp2 5 on emp2.deptno = emp1.deptno 6 and emp2.empno <= emp1.empno 7 group by emp1.rowid) emp2 8 on (emp2.rid = emp1.rowid) 9 when matched then 10 update set emp1.sal2 = nvl(emp2.sal, 0); Done SQL> select count(*) from emp1 where sal1 <> sal2; COUNT(*) ---------- 0