用通配符進行過濾
LIKE 操作符
%
表示任何字符出現的任意次數(0個、1個或多個字符)。
SELECT prod_id, prod_name FROM products WHERE prod_name LIKE 'jet%';
%告訴 MySQL 接受 jet 之后的任意字符,不管它有多少字符。根據 MySQL 的配置方式,搜索是可以區分大小寫的。
SELECT prod_id, prod_name FROM products WHERE prod_name LIKE '%anvil%';
通配符可以在任意位置,而且是可以多個。
%并不能匹配到 NULL
下劃線(_)通配符
下劃線與%一樣,但是下劃線只匹配單個字符而不是多個字符。
mysql> SELECT prod_id, prod_name FROM products WHERE prod_name LIKE '_ ton anvil';
+---------+-------------+
| prod_id | prod_name |
+---------+-------------+
| ANV02 | 1 ton anvil |
| ANV03 | 2 ton anvil |
+---------+-------------+
2 rows in set (0.00 sec)
和下面的做區分:
mysql> SELECT prod_id, prod_name FROM products WHERE prod_name LIKE '% ton anvil';
+---------+--------------+
| prod_id | prod_name |
+---------+--------------+
| ANV01 | .5 ton anvil |
| ANV02 | 1 ton anvil |
| ANV03 | 2 ton anvil |
+---------+--------------+
3 rows in set (0.00 sec)
** 與%能匹配0個字符不一樣,_總是匹配一個字符,不多也不少。 **
通配符使用技巧
雖然通配符很有用,但是這種功能是由代價的:通配符檢索的處理一般要比前面討論的其他搜索所花的時間更長。
如果其它操作符可以達到目的,盡量不要用通配符
如果確實要使用通配符,除非絕對有必要,否則不要把它們放在搜索模式的開始處,放在開始處,搜索起來是最慢的。
用正則表達式進行搜索
需要注意的是 MySQL僅支持多數正則表達式實現的一個很小的子集。
基本字符匹配
# 與文字正文1000匹配的一個正則表達式
SELECT prod_name FROM products WHERE prod_name REGEXP '1000' ORDER BY prod_name;
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '.000' ORDER BY prod_name;
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.01 sec)
.
表示匹配任意一個字符。
進行 OR 匹配
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '1000|2000' ORDER BY prod_name;
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.01 sec)
|
表示匹配其中之一。
兩個以上的 OR 條件:1000 | 2000 | 3000
匹配幾個字符之一
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '[123] Ton' ORDER BY prod_name;
+-------------+
| prod_name |
+-------------+
| 1 ton anvil |
| 2 ton anvil |
+-------------+
2 rows in set (0.00 sec)
[123] Ton
是[1|2|3] Ton
的縮寫,但是一定要加[]
,1|2|3 Ton
的意思是匹配1, 2, 或3 Ton。
在集合的開始位置放一個^
表示字符集合的否定,即將匹配除指定字符外的任何東西:[^123]
匹配1、2、3這些字符外的任何東西。
匹配范圍
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '[1-5] Ton' ORDER BY prod_name;
+--------------+
| prod_name |
+--------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
+--------------+
[0123456789]
表示匹配數字0到9,為了簡化這種類型的集合,可用[0-9]
表示。
范圍不限于完整的集合:[1-3],[6-9]。
范圍不限于數值:[a-z]匹配任意字母字符。
匹配特殊字符
要匹配特殊字符,需要用\\為前導
,也就是所謂的轉義。
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '\\.' ORDER BY prod_name;
+--------------+
| prod_name |
+--------------+
| .5 ton anvil |
+--------------+
正則表達式內具有特殊意義的所有字符都必須轉義以達到它原本意義。
\\
也用來引用元字符:
元字符 | 說明 |
---|---|
\f | 換頁 |
\n | 換行 |
\r | 回車 |
\t | 制表 |
\v | 縱向制表 |
匹配反斜杠\
需要使用\\\
。
匹配字符類
為了方便,可以使用預定義的字符集,稱為字符類(character class)
類 | 說明 |
---|---|
[:alnum:] | 任意字母和數字(同[a-zA-Z0-9]) |
[:alpha:] | 任意字符-[a-zA-Z] |
[:blank:] | 空格和制表-[\t] |
[:cntrl:] | ASCII控制表符-ASCII0到31和127 |
[:digit:] | 任意數字-[0-9] |
[:graph:] | 與[:print:]相同,但不包括空格 |
[:lower:] | 任意小寫字母-[a-z] |
[:print:] | 任意可打印字符 |
[:space:] | 包括空格在內的任意空白字符-[\f\n\r\t\v] |
[:upper:] | 任意大寫字母-[A-Z] |
[:xdigit:] | 任意十六進制數字-[a-fA-F0-9] |
匹配多個實例
重復元字符:
元字符 | 說明 |
---|---|
* | 0或多個匹配 |
+ | 1個或多個匹配-{1,} |
? | 0個或1個匹配-{0, 1} |
{n} | 指定數目的匹配 |
{n, } | 不少于指定數目的匹配 |
{n, m} | 匹配數目的范圍-m 不超過255 |
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '\\([0-9] sticks?\\)' ORDER BY prod_name;
+----------------+
| prod_name |
+----------------+
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '[[:digit:]]{4}';
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
等價于:
SELECT prod_name FROM products WHERE prod_name REGEXP '[0-9][0-9][0-9][0-9]'
定位符
前面講的都是匹配一個串中任意位置的文本,為了匹配特定位置的文本,需要使用定位符。
元字符 | 說明 |
---|---|
^ | 文本的開始 |
$ | 文本的結尾 |
[[:<:]] | 詞的開始 |
[[:>:]] | 詞的結尾 |
找出一個數(包括以小數點開始的數)開始的所有產品:
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '^[0-9\\.]' ORDER BY prod_name;
+--------------+
| prod_name |
+--------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
+--------------+
^的雙重用途 在集合中[]用來否定該集合,否則用來指串的開始處。
使 REGEXP 起類似 LIKE 的作用
LIKE 和 REGEXP 的不同在于,LIKE 匹配整個串,而 REGEXP 匹配子串。利用定位符,通過^
開始每個表達式,用$
結束每個表達式,可以使 REGEXP 的作用和 LIKE 一樣。