更新組合值

2021-07-13 06:54:34 字數 3005 閱讀 9535

好久沒有靜下心來寫東西了,    1 是沒有遇到好的案例   2 是最近好像 有點忙,  但又有點不知道自己在忙啥的感覺一樣。 強制自己靜下心寫東西, 但這時候 又覺得 自己囉嗦,闡述

點東西說了 很多, 又不知道自己 在說什麼。  好了廢話 不說 上正題

開發需要支援乙個 sql,  現有邏輯是 更新 a表 name 字段,   需要通過id關聯b表。然後把b的name,賦值給a表的name 值。 本來這個pl/sql 有。 但是現在 邏輯 變了。

說是 根據現在這個邏輯基礎上, 如果 b表 中多個資料字段type 欄位的值 為1, 則彙總b表所有name 的值,最後賦值給 a表資料。

這個需求 看似不難, 但是我後來做的過程中發現不少坑,   1  b表多條資料 和a表 關聯上,  但是滿足條件的 b表的name  值 一樣,  最終導致 a表中 的name 更新後 

如『張三,張三,張三,張三』。 經過確認後 只要 乙個張三 就可以。  這個又設計到  欄位中重複資料去重?? 咋辦??

另外如果  b表資料關聯 有 20 多個!導致 a表的name 值過長! 此時 又經過確認, 擷取 3個 不同值 就可以, 本來我打算 擷取3 個最新的值,我想到的是,正規表示式。 但是木有必要。  能簡單點就簡單點吧。

考慮再三,  同乙個字串去重, 過於複雜 需要用 樹形函式 分隔, 我想到 用 想到 相鄰 函式 判斷 相等,則為空, 然後在分組 資料中把  name 值提取出來。

還有就是效能問題,  a表 2個g,b表 2g。 2 g關聯 2g, 關聯分組,去重, 擷取。 更新 沒有優化的話,  估計在半小時 開外。  那就優化。最終sql

declare  

cursor datacur is   

with taba as(

select /*+ materialize */ order_id, main_wo_flag, party_name, count(1) over(partition by order_id) cnt  from

uos_work_order uwo where    main_wo_flag = '1' and uwo.arch_flag = 0   

),tabb as(

select /*+ materialize */ order_id, main_wo_flag, party_name, 

case when lag(party_name  ) over(partition by order_id order by party_name) =  party_name then null else  party_name end  party_name2 

from  taba where cnt>1

), tabc as( select /*+ materialize */  order_id,  to_char(wm_concat( party_name2)) party_name  from    tabb  

group by   order_id

), tabd as( select /*+ materialize */  rowid rid,uot.id  from  uos_order_track uot  )   

select  rid, regexp_replace(party_name,'^([^,]+)(,)([^,]+)(,)([^,]+)(,)(.*)$','\1\2\3\4\5\6')  from  

tabc, tabd  where tabc.order_id = tabd.id order by 1; 

type rowid_table_type is table of  rowid index  by  pls_integer;  

type cur_org_name_type is  table of  varchar2(255); 

v_rowid         rowid_table_type;

v_cur_org_name  cur_org_name_type; 

begin  

open datacur; 

loop

fetch datacur  bulk collect  into  v_rowid, v_cur_org_name  limit 20000;

dbms_output.put_line( 'v_rowid.count:'||v_rowid.count );

forall i in v_rowid.first ..v_rowid.last

update uos_order_track  set cur_org_name =  v_cur_org_name(i) where rowid = v_rowid(i) ;  

commit;        

exit when  datacur%notfound;

end loop;

close datacur;  

end; 

綜合性能 穩定 在2 分組之內, 這個可是 大表,大表關聯更新哦。。。。

with taba as  提取資料, 提高效能

select  rid, regexp_replace(party_name,'^([^,]+)(,)([^,]+)(,)([^,]+)(,)(.*)$','\1\2\3\4\5\6')   表示式 擷取  第三個逗號前面的 字串。  

case when lag(party_name  ) over(partition by order_id order by party_name) =  party_name then null else  party_name end  party_name2  上一條資料 如果一樣 則為null.

wm_concat( party_name2)  合併字串,  10g中, 11g不建議用。

order by 1  很重要, 提公升效能關鍵, 這個就不說了, 太多,避免囉嗦。

fetch datacur  bulk collect  into  v_rowid, v_cur_org_name  limit 20000;  批量游標,  減少 sql 引警  搜尋引擎 頻換 切換。   limit 20000  防止 回滾段 壓力過大,  

練習,求組合公式值

求組合數公式為 編一程式,輸入m和n 的值,求組合數。要求分別定義求階乘和求組合的函式,求組合數的函式呼叫求階乘的函式來實現求解,在 main 函式中,負責輸入輸出及呼叫求組合數的函式。include using namespace std int fac int int main int m,n ...

列舉值的組合使用

有時候列舉只返回一項會顯得不夠用,比如新建乙個列舉型別week它總共有7項分別代表週日到周一,宣告乙個week型別的列舉值work用來表示乙個人的值日安排,這個人的值日安排可能不止一天,如果work的值只能為week7個列舉項中的乙個顯然是不夠用的。這時候就需要用到列舉的組合。想要使用列舉的組合就需...

組合數學隨筆(更新中)

mathrm c n m frac mathrm a n m frac 1.不同球n,不同盒子m,可為空,全放入方案數 每個球m種方法,ans m n 2.不同球,不同盒,不可為空 先思考不同球,相同盒子,不可為空 設 f n m 為方案數,那麼對於乙個球而言,可以選擇放入前面放過的盒子,也可以新開...