假設(shè)有一張表oldyang_bayern,取其中的10條數(shù)據(jù)作為參考:
現(xiàn)在需要合并此張表中姓名重復(fù)的數(shù)據(jù),將符合條件的字段值,合并到重名數(shù)據(jù)中ID最高的那一條。
要合并的字段分為三種情況:
1. 常規(guī)字段(DEPARTMENT/JOBTITLE):取重名數(shù)據(jù)中ID最高的非空值,例如“施魏因施泰格”的DEPARTMENT字段合并后,應(yīng)取值“組織部”;
2. 依據(jù)數(shù)值大小取值的字段(SALARY):取重名數(shù)據(jù)中的最大值;
3. 非常規(guī)字段(CITY/DITRICT/ADDRESS/ADDRESSRANK):這些字段都與地址相關(guān),以ADDRESSRANK最高的那條數(shù)據(jù)為準(zhǔn)(ADDRESSRANK由高到低分別為S|A|B|C|D),然后取此條數(shù)據(jù)中的CITY/DITRICT/ADDRESS值;如果ADDRESSRANK相同,取ID最高的數(shù)據(jù)。
依據(jù)以上條件,此前的10條數(shù)據(jù)合并后的結(jié)果應(yīng)如下所示:
我所給出的方法:
處理合并的存儲(chǔ)過(guò)程 prc_oldyang_bayern
create or replace procedure prc_oldyang_bayern(pname varchar2) is cursor cur is select * from oldyang_bayern where name=pname order by id desc; --NAME相同的數(shù)據(jù)按id降序排列 --申明記錄表info_table,用于存放NAME相同的數(shù)據(jù) type info_table_type is table of oldyang_bayern%ROWTYPE index by binary_integer; info_table info_table_type; info_dest oldyang_bayern%rowtype; nCount number(2):=0; --計(jì)數(shù)變量 vi number(2); --在更新地址字段時(shí)將會(huì)用于放入記錄號(hào) begin open cur; --通過(guò)循環(huán)計(jì)數(shù)的方式將重復(fù)的記錄放入記錄表 loop nCount:= nCount+1; fetch cur into info_table(nCount); exit when cur%notfound; end loop; close cur; nCount := nCount - 1; --更新常規(guī)字段DEPARTMENT/JOBTITLE for i in 1..nCount-1 loop if i = 1 then info_dest.DEPARTMENT:= nvl(info_table(i).DEPARTMENT, info_table(i+1).DEPARTMENT); else info_dest.DEPARTMENT:= nvl(info_dest.DEPARTMENT, info_table(i+1).DEPARTMENT); end if; end loop; for i in 1..nCount-1 loop if i = 1 then info_dest.JOBTITLE:= nvl(info_table(i).JOBTITLE, info_table(i+1).JOBTITLE); else info_dest.JOBTITLE:= nvl(info_dest.JOBTITLE, info_table(i+1).JOBTITLE); end if; end loop; --更新SALARY字段 for i in 1..nCount-1 loop if i = 1 then info_dest.SALARY:= greatest(nvl(info_table(i).SALARY,-1), nvl(info_table(i+1).SALARY,-1)); else info_dest.SALARY:= greatest(nvl(info_dest.SALARY,-1), nvl(info_table(i+1).SALARY,-1)); end if; end loop; info_dest.SALARY:= replace(info_dest.SALARY,-1); --處理當(dāng)SALARY為空值時(shí)的狀況 --更新與ADDRESSRANK相關(guān)的字段 --此處引用了一個(gè)自定義函數(shù)fun_get_ranknum --利用這個(gè)函數(shù)將地址等級(jí)S|A|B|C|D轉(zhuǎn)換成對(duì)應(yīng)的地址等級(jí)序號(hào)1|2|3|4|5(函數(shù)代碼會(huì)在后面列出) --接著拼接地址等級(jí)序號(hào)+記錄號(hào),取拼接后最小值 --此方法用于處理當(dāng)ADDRESSRANK相同時(shí),取ID最高的那條ADDRESSRANK相關(guān)記錄 --(注:在游標(biāo)中記錄已按ID降序排列) for i in 1..nCount-1 loop if i = 1 then info_dest.ADDRESSRANK:= least(fun_get_ranknum(info_table(i).ADDRESSRANK)||i, fun_get_ranknum(info_table(i+1).ADDRESSRANK)||i+1); else info_dest.ADDRESSRANK:= least(info_dest.ADDRESSRANK, fun_get_ranknum(info_table(i+1).ADDRESSRANK)||i+1); end if; end loop; vi:= regexp_substr(info_dest.ADDRESSRANK, '\d$'); --使用正則表達(dá)式取出拼接值中的記錄號(hào) info_dest.ADDRESSRANK:=info_table(vi).ADDRESSRANK; info_dest.CITY:=info_table(vi).CITY; info_dest.DISTRICT:=info_table(vi).DISTRICT; info_dest.ADDRESS:=info_table(vi).ADDRESS; --將篩選后的變量值更新到ID最高的記錄當(dāng)中 update oldyang_bayern set DEPARTMENT=info_dest.DEPARTMENT, JOBTITLE=info_dest.JOBTITLE, SALARY=info_dest.SALARY, CITY=info_dest.CITY, DISTRICT=info_dest.DISTRICT, ADDRESS=info_dest.ADDRESS, ADDRESSRANK=info_dest.ADDRESSRANK where id = info_table(1).id; --刪除重復(fù)的記錄 delete from oldyang_bayern where name=pname and id != info_table(1).id; commit; end ;
?
存儲(chǔ)過(guò)程中所用到的自定義函數(shù) fun_get_ranknum
create or replace function fun_get_ranknum(prank in varchar2) return varchar2 is Result varchar(2); vcTemp varchar(2); begin vcTemp:=prank; case when vcTemp = 'S' then vcTemp:= '1'; when vcTemp = 'A' then vcTemp:= '2'; when vcTemp = 'B' then vcTemp:= '3'; when vcTemp = 'C' then vcTemp:= '4'; when vcTemp = 'D' then vcTemp:= '5'; when vcTemp is null then vcTemp:= '9'; end case; Result := vcTemp; return(Result); exception when others then Result := '9'; return result; end ;
?
利用匿名塊傳遞重復(fù)姓名到prc_oldyang_bayern,執(zhí)行合并過(guò)程
declare cursor cur is select name from oldyang_bayern group by name having count(*)>1; rec cur%rowtype; begin open cur; loop fetch cur into rec; exit when cur%notfound; prc_oldyang_bayern(rec.name); end loop; close cur; end;
?轉(zhuǎn)自: http://www.oldyang.com/2009/06/23/using_plsql_remove_duplicates/
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
