查看測試數據
select * from student;
1. like
在where字句中使用like可以達到模糊查詢的效果,常用通配符如下
▶ %: 使用 % 有三種情況
① 字段 like ‘%關鍵字%’字段包含”關鍵字”的記錄
select * from student where stu_name like '%一%';
查詢結果是stu_name字段中所有包含“一”關鍵字的記錄。
② 字段 like ‘關鍵字%’字段以”關鍵字”開始的記錄
select * from student where stu_name like '一%';
查詢結果是stu_name字段中所有以“一”關鍵字開始的行。
③ 字段 like ‘%關鍵字’字段以”關鍵字”結束的記錄
select * from student where stu_name like '%一';
查詢結果是stu_name字段中所有以“一”關鍵字結束的記錄。
▶ _:單一任何字符,只能匹配單個的字符,使用示例如下
select * from student where stu_name like '_一';
查詢結果為只有兩個字符,並且第二個字符為“一”的記錄。
select * from student where stu_name like '_一_';
查詢結果為只有三個字符,並且第二個字符為“一”的記錄。
select * from student where stu_name like '_一%';
可以與通配符%一起使用,查詢結果為第二個字符為“一”的所有記錄。
2. regexp_like
▶ []: 實際應用中,會碰到要查詢在某一范圍內的字符,表示括號內所列字符的一個,類似正則表達式。指定一個字符、字符串或范圍,要求所匹配對象為它們中的任一個。
① 查詢名為“一”,姓“劉李孫”的學生姓名
--錯誤示范,無法查詢到結果
select * from student where stu_name like '[劉李孫]一';
--正確示范
select * from student where regexp_like(stu_name,'[劉李孫]一');
② 查詢[]內有一系列字符,如1234,abcd等記錄
--錯誤示范,無法查詢到結果
select * from student where stu_name like '趙[1-9]';
--正確示范
select * from student where regexp_like(stu_name,'趙[1-9]');
注意:[]不能與%或者_一起使用。無法查詢到正確的結果。
▶ ^:不在某個范圍內
① 查詢名為“一”,姓不是“劉李孫”的學生姓名
--錯誤示范,無法查詢到結果
select * from student where stu_name like '[^劉李孫]一';
--正確示范
select * from student where regexp_like(stu_name,'[^劉李孫]一');
3. Instr(StrSource,StrTarget)
instr函數也有三種情況:
① instr(字段,’關鍵字’)>0相當於 字段like ‘%關鍵字%’
② instr(字段,’關鍵字’)=1相當於 字段like ‘關鍵字%’
③ instr(字段,’關鍵字’)=0相當於 字段not like ‘%關鍵字%’
--特殊用法:
select * from student where instr('李一,劉一', stu_name) > 0;
--不完全等價於
select * from student where stu_name = '李一' or stu_name = '劉一';
這種特殊用法會獎滿足條件的條件的字符串,和單個字符串數據都篩選出來。數據規范的情況下,這兩者是等價的。
數據量比較小的時候,使用like,數據量較大情況下,使用instr,數據量更大情況下,使用Oracle的instr函數與索引配合提高模糊查詢的效率。
4. like、instr性能測試
很多時候,我們要進行字符串匹配,在SQL語句中,我們通常使用like來達到我們搜索的目標。但經過實際測試發現,like的效率與instr函數有相當大的差別。
① 1000多萬條數據,測試時like的效率與instr函數差別不是特別大。
select count(*) from student;
--數據結果:11855410
select count(*) from student where stu_name like '%王%';
--數據結果:702077
--測試時間:1.966秒
select count(*) from student where instr(stu_name,'王');
--數據結果:702077
--測試時間:2.137秒
② 億級數量級,測試結果instr效果明顯好於like。
select count(*) from student;
--數據結果:2244661391
select count(*) from student where stu_name like '%王%';
--數據結果:415065640
--測試時間:86.939秒
select count(*) from student where instr(stu_name,'王');
--數據結果:415065640
--測試時間:60.591秒
為提高效率,我們在stu_name字段上可以加上非唯一性索引,這樣,再使用這樣的語句查詢,效率可以提高不少,表數據量越大時兩者差別越大。
✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍擴展閱讀✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍
5. 正則表達式
oracle 10g 增加的正則表達式函數有以下四種:
regexp_like() --返回滿足條件的字段
regexp_instr() --返回滿足條件的字符或字符串的位置
regexp_replace() --返回替換后的字符串
regexp_substr() --返回滿足條件的字符或字符串
這四個函數的功能分別對應傳統sql的 like操作符 和 instr 、replace 、substr函數,
在一般的、不怎么復雜的模式匹配中,使用傳統的sql函數就能滿足,當需要實現的操作
比較復雜時,使用正則表達式函數,就可以寫出簡潔、強大的sql語句。
匹配過程中可能會涉及到的元字符(Meta Character)對應的sql代碼:
^ 使表達式定位至一行的開頭
$ 使表達式定位至一行的末尾
* 匹配0次或更多次
? 匹配0次或1次
+ 匹配1次或更多次
{m} 正好匹配m次
{m,} 至少匹配m次
{m,n} 至少匹配m次但不超過n次
[:alpha:] 字母字符,匹配字符A-Z、a-z
[:lower:] 小寫字母字符,匹配字符a-z
[:upper:] 大寫字母字符,匹配字符A-Z
[:digit:] 數字,匹配數字0-9
[:alphanum:] 字母數字字符,匹配字符A-Z、a-z、0-9
[:space:] 空白字符(禁止打印),如回車、換行符、豎直制表符和換頁符[:punct:] 標點字符
[:cntrl:] 控制字符(禁止打印)
[:print:] 可打印字符|分隔替換選項,通常與分組符()一期使用
() 將子表達式分組為一個替換單元,量詞單元或后向引用單元
[char] 字符列表
. 匹配除null之外的任意單個字符
/ 要匹配的字符是一個特殊字符、常量或者后者引用
x|y 匹配 x 或 y
[abc] 匹配abc中的任何單個字符
[a-z] 匹配 a 到 z 范圍內的任意單個字符
✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍擴展閱讀✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍✍