Oracle經過一個字段的值將一條記錄拆分爲多條記錄

前言

以前遇到了一次這樣的需求,當時沒有記錄,這一次又遇上了,簡單的記錄一下。正則表達式

本文我的拙見,如有出入,請指出——來自菜的顫抖sql

場景

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

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

因此必須將分號分割的記錄,拆分紅單獨的記錄。
單個記錄
變成:
切割後code

實現

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

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

其中regexp_substr各個參數的含義:blog

  • 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類似,string

SELECT LEVEL FROM DUAL CONNECT BY LEVEL <=2;

level
因此再回到最初的sql,也就很好理解了。select

最後

此致,敬禮im

相關文章
相關標籤/搜索