1.通配符
通配符一般使用LIKE關鍵字來進行連接,常用的通配符符號有%和_。
通配符的使用在我們對查找條件並不是特別明確的時候可以幫助我們過濾數據。
例如,查找NAME中含有“林”的結果。
SELECT NAME FROM TABLE1 WHERE NAME LIKE %林% ORDER BY NAME;
SELECT NAME FROM TABLE1 WHERE NAME LIKE 林_ ORDER BY NAME;
上面兩個代碼段主要的區別就是%和‘’的區別,其中‘’只能用來表示一個字符的位置,%可以用來表示任意多的字符。
與%能匹配0個字符不同的是,_只能匹配一個字符,不能多也不能少。
值得注意的是%似乎可以表示任意字符,但是不可以表示null
而且通配符在使用的時候的確給我們帶來了方便,但是其實他的實際查找效率並不是很高,應該儘量減少使用,特別是不要在搜索模式的開始處使用通配符,此時的效率是最低的。
2.正則表達式
先看以下例子:
SELECT NAME FROM TABLE1 WHERE NAME REGEXP '1000' ORDER BY NAME;
以上語句表示的是查找NAME中包含‘1000’的行。
REGEXP關鍵字後面跟着的就是正則表達式的內容。
此時看上去似乎和使用LIKE的語句沒有什麼不同,體現不出正則表達式的優點,接着往下看。
再看一個例子:
SELECT NAME FROM TABLE1 WHERE NAME REGEXP '.000' ORDER BY NAME;
這中間的‘.’表示的是匹配 任意一個 字符。即1000,2000都能被匹配到。
此時注意LIKE _000;和.000的區別,前一種情況表示000必須是最後的字符,前面可以任意替換,而後者則表示的是隻要值中含有對應的000就可以返回該行。
這時我們體會一下以下兩種表達方式的區別:
SELECT NAME FROM TABLE1 WHERE NAME LIKE '1000';
SELECT NAME FROM TABLE1 WHERE NAME REGEXP '1000';
這個時候會發現在一定的情況下第一種情況不會返回任何結果,第二種情況會返回結果。
因爲LIKE匹配的是整列,即只有當值是1000的時候,纔會返回相應的結果,而REGEXP表示的是當值中只要包含1000就返回。即LIKE必須是完全等於值才返回,REGEXP只需要包含值就返回。
那REGEXP能不能用來匹配整個值呢?(像LIKE一樣),答案是肯定的,下文會講到。
正則表達式中可以使用‘ | ’來表示OR的操作:
SELECT NAME FROM TABLE1 WHERE NAME REGEXP '1000' | '2000';
表示返回NAME中包含‘1000’或者‘2000’的行。
匹配特定的單一字符:
SELECT NAME FROM TABLE1 WHERE NAME REGEXP '[123]TOM';
[123]指的是該位置的單一字符是‘1’或者‘2’或者‘3’,其中的[123]其實是[1|2|3]的縮寫形式。
此時的[]不可省略!
即返回NAME中包含1TOM,或者2TOM,或者3TOM的行。、
此時如果[]中的數值太多,如[123456789],可以寫爲[1-9]。
前面說到了‘.’,在正則表達式中表示的是任意單個字符,那麼如果我們需要返回含有.的行,如果用下面的語句:
SELECT NAME FROM TABLE1 WHERE NAME REGEXP '.';
顯然返回的是所有行,這並不是我們所想要的輸出結果。
這個時候就需要用到計算機網絡中數據鏈路層中封裝成幀中的轉義字符的思想,此時的轉義字符爲’\\',以下語句才能返回我們想要的結果:
SELECT NAME FROM TABLE1 WHERE NAME REGEXP '\\.';
這樣的結果才返回的是含有.的行。
正則表達式中的字符類:
類 | 說明 |
---|---|
[:alnum:] | 任意字母和數字 |
[:alpha:] | 任意字符 |
[:blank:] | 空格和製表 |
[:cntrl:] | ASCII控制字符 |
[:digit:] | 任意數字 |
[:graph:] | 與[:print:]但不包括空格 |
[:lower:] | 任意小寫字母 |
[:print:] | 任意可打印字符 |
[:punct:] | 任意不在 [:alnum:], [:cntrl:]中的字符 |
[:space:] | 包括空格在內的任意空白字符 |
[:upper:] | 任意大寫字母 |
[:xdigit:] | 任意十六進制數字 |
正則表達式中的重複元字符:
元字符 | 說明 |
---|---|
* | 0個或者多個匹配 |
+ | 1個或多個匹配(相當於{1, }) |
? | 0個或多個匹配(相當於{0,1}) |
{n} | 指定n個數目匹配 |
{n, } | 不少於n個數目匹配 |
{n,m} | 匹配數目指定範圍 |
下面舉幾個例子:
SELECT NAME FROM TABLE1 WHERE NAME REGEXP '[[:digit:]]{4}';
其中,[[:digit:]]表示任意數字,{4}表示指定數目爲4,即返回NAME中帶有4個任意數字的行。
SELECT NAME FROM TABLE1 WHERE NAME REGEXP '\\([0,9] sticks?\\)';
其中,‘\\(’意思是匹配左括號‘(’,[0,9]意思是0到9的任意數字,stick?表示匹配stick或者sticks,這裏的?表示?前面的s可以有也可以沒有,即stick和sticks都符合要求,;‘\\)’匹配右括號‘)’。
符合上述語句的要求的例子是:TNT (1 stick)或者TNT (5 sticks)。
到目前爲止使用正則表達式匹配一個串中任意位置的文本,如果我們要匹配指定位置的文本,則就需要用到定位符。
元字符 | 說明 |
---|---|
^ | 文本的開始 |
$ | 文本的結尾 |
[[:<:]] | 詞的開始 |
[[:>:]] | 詞的結尾 |
SELECT NAME FROM TABLE1 WHERE NUMBER REGEXP '^[0-9\\.]';
上面的語句表示查找以一個數。包括小數點在開頭的NAME屬性的行。