Oracle SQL 查詢優化.Part5

一、字符串

1. 字符串截取:

語法:substr(string, start, length),其中 string 是要截取的字符串,start 是開始的字符下標,length 是截取的長度。同時可以結合使用 instr 函數判斷子串的位置,從字串第一次出現的位置開始截取。

-- 字符串截取
select substr(empdesc, instr(empdesc, ',') + 1, instr(empdesc, '。')) str from emp;

在使用 instr 的時候需要注意,如果子串不存在的話,instr 返回的是 0。

-- 如果子串不存在,返回 0
select instr(empdesc, 'a') index_a from emp;

2. 字符串中包含引號:

如果字符串中包含單引號,需要敲兩次,字符串中兩個單引號輸出一個單引號:

-- 字符串中包含單引號
select 'Servyou''s Future!' str from dual;

除此之外,從 Oracle 10g 開始引入了 q-quote 特性:按照指定規則,字符串前後使用界定符 “ ' ” 。其中 q-quote 的寫法規則是:a. q-quote 界定符可以是除了 Tab、空格、回車外任何單字符或者多字節字符;b. 界定符可以是 {}、[]、<>、(),但必須是成對出現。

-- q-quote 特性、界定符
select q'{Servyou's Future!}' t_group,
       q'[Dqy's Dream!]' t_dept,
       q'(Persons' benifit)' t_person
  from dual;

3. regexp_count —— 計算字符在字符串中出現的次數:

-- 計算字符在字符串中出現的次數
select regexp_count(q'[Servyou's future is Dqy's dream, it can bring persons' benifit]', q'[']') quote_count from dual;

4. regexp_replace —— 字符串替換

regexp_replace 正則功能強大,下邊舉例可以實現的一些需求:

  • 刪除不必要字符
-- 刪除不必要字符
select regexp_replace('Hello Oracle SQL!', 'Oracle ') replace_res from dual;
  • 將字符和數據分離
-- 將數字字符與字母分離
select regexp_replace(empno, '[0-9]', '') empno_char,
       regexp_replace(empno, '[^0-9]', '') empno_num
  from emp;

這裏, ^ 字符放在括號裏表示否定。但是如果  ^ 放在括號外邊表示字符串開始,下邊會遇到。當然這裏也可以用前幾個part 中講的 translate 函數實現:

-- translate 實現
select translate(empno, 'a0123456789', 'a') emp_char,
       translate(empno, '0123456789' || empno, '0123456789') emp_num
  from emp;

5. regexp_like —— 正則 like

regexp_like 對應普通的like,用在 where 子句中。

-- 查詢只包含字母數字型的數據
select empname from emp where regexp_like(empname, '^[0-9a-zA-Z]+$');
                     

這裏,對正則用到的字符做一下說明:

^ : 字符串起;$ : 字符串終;+ : 表示匹配前邊字符串 1 次或多次;* : 表示匹配字符串 0 次或多次。

再舉幾個例子:

regexp_like(str, '[A]')       相當於       (like '%A%')

regexp_like(str, '[ABC]')     相當於       (like '%A%' or like '%B%' or like '%C%')

regexp_like(str, '^A')        相當於       (like 'A%')

regexp_like(str, 'A$')        相當於       (like '%A')

regexp_like(str, '^A$')       相當於       (like 'A')

6. listagg —— 根據表中的行創建一個分隔列表

個人理解就是行合併,轉爲一個字段。其中 wmsys.wm_concat 也可以實現這樣的需求,但是 wmsys.wm_concat 是一個非公開函數,具有不確定性,大多都不推薦使用。Oracle 11.2 版本開始有了 listagg 函數:

-- listagg 函數
select deptno,
       listagg(empno, ', ') within group (order by deptno) empno_str,
       listagg(empname, ', ') within group (order by deptno) empname_str
  from emp
group by deptno;





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章