Oracle中 如何用一個表的數據更新另一個表中的數據


准備階段

1.建表語句:

create table table1(  
idd varchar2(10) ,  
val varchar2(20)  
); 
create table table2(  
idd varchar2(10),  
val varchar2(20)  
);

2.插入數據:

insert into table1 values ('01','1111');
insert into table1 values ('02','222');  
insert into table1 values ('02','2222');    
insert into table1 values ('03','3333');  
insert into table1 values ('04','4444');
insert into table1 values ('06','6666');
commit;  
insert into table2 values ('01','aaaa');
insert into table2 values ('02','bbbb');      
insert into table2 values ('03','cccc'); 
insert into table2 values ('04','dddd');
insert into table2 values ('05','eee');
commit; 

3.兩張表如下圖:
image.png

image.png

要將 table2中idd - val 的值,賦值給table1對應的 idd - val;
為了驗證操作的合理性,設置了如下幾個需要額外考慮情況:
注意兩表特殊地方在於:

  • table1中,有1條idd字段值為06的數據,table2中idd字段沒有06,命名為 e1
  • table1中,有2條idd字段值都為02,並且對應的val 不同的數據,命名為 e2,以下都能正常解決此情況;
  • table2中,有2條idd字段值都為05,但對應的val值不同的數據,命名為 e3,待添加;

sql查詢:

1. 最容易想到的辦法:通過子查詢 ,直接 update ,如下:

update table1 set table1.val = (select val from table2 where table1.idd = table2.idd);

image.png

  • 問題:我們遇到了e1情況,即table1中06對應的值被改變了-->val變成了null(即圖中的空白);
    這並不是我們的本意,故做出如下改進。

2. 加入限制條件,對於 table1中有值,但是table2中無值的idd字段,不做修改;

update table1 set val = (select val from table2 where table1.idd = table2.idd)
where exists (select 1 from table2 where table1.idd = table2.idd)

image.png

  • 第2種寫法看似沒問題,但如果我們再次向table2中插入一條數據,
    insert into table2 values ('03','ccc'); 遇到了e3情況,
  • 執行后會報錯如下:
    ORA-01427:單行子查詢返回多個行
    image.png

3. 通過上述分析,簡單的更新語句並不能解決遇到的異常情況。所以我們可以使用merge,如下:

merge into table1
using  table2
on (table1.idd = table2.idd)
when matched then
update set table1.val = table2.val

4. 最后,在3的基礎上,加入限制條件,即可解決;

merge into table1
using  (select t.idd ,max(t.val) m from table2 t group by t.idd)table2
on (table1.idd = table2.idd)
when matched then
update set table1.val = table2.m
  • 上述寫法在using后面構造了一個新的table2,但一定要對val做出處理,如果是varchar類型,可以選擇 max,min等函數,如果number類型,可以使用sum,avg等函數,總之,要對val做出處理(對應多個的時候,到底要哪個?最大的還是最小的),新的table2是一個idd對應一個val。
  • 為什么構造新的table2時要加 group by t.idd ,因為 select max(t.val) m from table2 t 查詢的是一條數據,t.idd不屬於這條數據的任何字段,故select t.idd 后報錯,拼接group by t.idd便可以查出需要的idd字段。(針對oracle數據庫,mysql並不會)

參考:Oracle中用一個表的數據更新另一個表的數據
Group by 中avg();sum();min();max();count();的運用整理(Oracle的執行順序)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM