一、字符串
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;