工作和學習中常常會遇到一行要分割成多行數據的情況,在此整理一下做下對比。
單行拆分
如果表數據只有一行,則可以直接在原表上直接使用connect by+正則的方法,比如:
select regexp_substr('444.555.666', '[^.]+', 1, level) colfrom dualconnect by level <= regexp_count('444.555.666', '/.') + 1
輸出結果:
COL----444555666
多行拆分
如果數據表存在多行數據需要拆分,也可以在原表上使用connect+正則的方法:
方法一
with t as(select '111.222.333' colfrom dualunion allselect '444.555.666' colfrom dual)select regexp_substr(col, '[^.]+', 1, level)from tconnect by level <= regexp_count(col, '/./') + 1and col = prior coland prior dbms_random.value > 0
結果:
---------111222333444555666
方法二
使用構造的最大行數值關聯原表:
with t as(select '111.222.333' colfrom dualunion allselect '444.555.666' colfrom dual)select regexp_substr(col, '[^.]+', 1, lv)from t, (select level lv from dual connect by level < 10) bwhere b.lv <= regexp_count(t.col, '/./') + 1
這種方法設置第二個數據集的時候要小于可能的最大值,然后兩數據集做關聯,在做大數據量拆分的時候,這個數值設置得當,拆分行數相對一致的情況下,效率比方法一直接connect by要高。
方法三
使用table函數:
with t as(select '111.222.333' colfrom dualunion allselect '444.555.666' colfrom dual)select column_valuefrom t,table(cast(multiset(select regexp_substr(col, '[^.]+', 1, level) ddfrom dualconnect by level <= regexp_count(t.col, '/./') + 1) assys.odcivarchar2list)) a
結果:
COLUMN_VALUE-------------111222333444555666
這個方法輸出的列名是固定的,column_value依賴于sys.odcivarchar2list這個類型的輸出,該方法對于大數據量的拆分效率比第二個方法好。
方法四
with t as(select '111.222.333' colfrom dualunion allselect '444.555.666' colfrom dual)select regexp_substr(col, '[^.]+', 1, trim(column_value))from t,xmltable(concat('1 to ',regexp_count(t.col, '/./') + 1)) a ;
注意:大數據量的拆分時,謹慎使用正則的方法去做,可以使用substr+instr的方式替換正則。
如果以上方法的效率仍然不理想,可考慮使用plsql塊。
總結
以上就是本文關于Oracle數據行拆分多行方法示例的全部內容,希望對大家有所幫助。有什么問題可以隨時留言,歡迎大家交流討論。
新聞熱點
疑難解答