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属性的行。