用通配符进行过滤
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 一样。