ORACLE逗號分割的字串轉多行(轉載)
阿新 • • 發佈:2021-01-12
分割單行資料
我們需要使用REGEXP_SUBSTR
和REGEXP_COUNT
兩個ORACLE函式
function REGEXP_SUBSTR(string, pattern, position, occurrence, modifier)
string
:需要進行正則處理的字串pattern
:進行匹配的正則表示式position
:起始位置,從第幾個字元開始正則表示式匹配(預設為1)occurrence
:標識第幾個匹配組,預設為1modifier
:模式(‘i’不區分大小寫進行檢索;‘c’區分大小寫進行檢索。預設為’c’)
function REGEXP_COUNT ( string, pattern [, position [, match_param]])
返回pattern 在string串中出現的次數。如果未找到匹配,則函式返回0。position 變數告訴Oracle 在源串的什麼位置開始搜尋。在開始位置之後每出現一次模式,都會使計數結果增加1。
SELECT REGEXP_SUBSTR('B00053,D00058,D00094', '[^,]+', 1, LEVEL) VALUE
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT('B00053,D00058,D00094', '[^,]+')
- 1
- 2
- 3
分割後結果如下:
分割多行資料
我們有三行初始資料
WITH TEMP AS (SELECT T.VALUE, T.COUNTS, T.EXE_ID FROM SC_MONIT_EXERESULT T INNER JOIN SYS_TASK_EXECUTE A ON T.EXE_ID = A.EXEC_ID WHERE FIELD_CODE = 'fundList' AND A.BUSIDATE = '20180604' AND VALUE = 'B00053,D00058,D00094') SELECT REGEXP_SUBSTR(VALUE, '[^,]+', 1, LEVEL) VALUE, COUNTS, EXE_ID FROM TEMP CONNECT BY LEVEL <= REGEXP_COUNT(VALUE, '[^,]+')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
分割後資料變成了39行而不是9行!
問題出在使用connect by時,沒有類似 id=prior pid的條件,而是 connect by rownum<xxx 或 connect by level<xxx 時,每一條記錄都會作為自己或者其他記錄的子節點,也就說,每一條記錄的子節點就是表上所有的記錄。而樹的層數就是rownum(或是level)值。
假設表中有N條記錄,則記F(N,l)為select id,level from t connect by level<l 的結果集數目。那麼:
F ( N , 1 ) = N F(N,1)=NF(N,1)=N
l e v e l < = 3 level<=3level<=3 時,遞迴查詢到的樹狀結構:
我們需要給樹加上父子關係,用rownum
作為PK列
WITH TEMP AS
(SELECT T.VALUE, T.COUNTS, T.EXE_ID, ROWNUM ROWNUM1
FROM SC_MONIT_EXERESULT T
INNER JOIN SYS_TASK_EXECUTE A
ON T.EXE_ID = A.EXEC_ID
WHERE FIELD_CODE = 'fundList'
AND A.BUSIDATE = '20180604'
AND VALUE = 'B00053,D00058,D00094')
SELECT 'fundCode' FIELD_CODE,
REGEXP_SUBSTR(VALUE, '[^,]+', 1, LEVEL) VALUE,
COUNTS,
EXE_ID
FROM TEMP
CONNECT BY PRIOR ROWNUM1 = ROWNUM1
AND LEVEL <= REGEXP_COUNT(VALUE, '[^,]+')
AND PRIOR DBMS_RANDOM.VALUE() IS NOT NULL
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
PRIOR DBMS_RANDOM.VALUE() IS NOT NULL
告訴ORACLE每次迴圈是不一樣的,不然會報connect by死迴圈
最後得到的結果: