Oracle通過一個字段的值將一條記錄拆分為多條記錄


前言

之前遇到了一次這樣的需求,當時沒有記錄,這一次又趕上了,簡單的記錄一下。

場景

表A中存放了集裝箱的信息,一個集裝箱一條記錄,表B中存放了對於集裝箱操作的指令,一條指令包括多個集裝箱箱號,通過分號;切割(TCIU2347687;XUTR3546865),現在的需求是,對於已經在指令表B中的集裝箱,在查詢表A時需要過濾掉。

  • 很容易想到的是not in, 然而分號分割。
  • 其次,not like,然而[Err] ORA-01427: 單行子查詢返回多個行,表示like后面只接受模糊查詢的單個值。

所以必須將分號分割的記錄,拆分成單獨的記錄。
單個記錄
變成:
切割后

實現

Oracle可使用regexp_substr函數實現,實現上面切割的sql為:

select regexp_substr('TCIU2347687;XUTR3546865', '[^;]+', 1, level) JZXXH
from dual connect by level <= regexp_count('TCIU2347687;XUTR3546865', ';') + 1

其中regexp_substr各個參數的含義:

  • TCIU2347687;XUTR3546865 表示需要分割匹配的串(我這里只是做了示例,真實情況下是表的字段)。
  • [^;]+典型的正則表達式,我這里分號切割,因此確定分割規則是多個不是分號的字符,因此遇到分號便結束,完成一個串的獲取。
  • 1開始位置,最左端(Oracle下標都是1開始
  • level表示第幾個匹配上的。
    為了直觀點搞清楚這個函數,比如下面的語句:
select REGEXP_SUBSTR('aaa;bbb','[^;]+',1,1) AS STR FROM dual; 

結果就是aaa, 如果把第二個1變成2,輸出就是bbb
好了,這部分意圖很明顯了,下面就是把它每一個切割串取出來,看到上面取level個,而這個level是個什么東西呢,在這個之前,先看regexp_count(string, c)函數,這個函數其實很好理解,返回string中c的個數。
然后就是這個level,這是一個偽列,和RowNum相似,

SELECT LEVEL FROM DUAL CONNECT BY LEVEL <=2; 

level
所以再回到最初的sql,也就很好理解了。


最后

  • 本文內容個人拙見,若有出入,歡迎指正。
  • 歡迎賞臉關注:家佳Talk

歡迎賞臉關注:家佳Talk


免責聲明!

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



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