同系列的第八篇,上一篇在:http://blog.csdn.net/jiluoxingren/article/details/48402885
前面的几章讲解了搜索的许多复杂的用法。然而提供再多的条件,还是无法满足我们的需求。因为我们不一定能够获得一个精确的条件来对数据进行检索。所以如果能够提供模糊的匹配,能使我们的搜索更加容易。
不等条件
此前我们使用的条件都是用“=”来确定的,实际上对于数字类型(包括时间与日期)的数据,我们更多的是使用“>”(大于),“<”(小于),“>=”(大于等于),“<=”(小于等于),“<>”(不等于)。
例如我们可以按上一篇的方法,添加一个年龄Age字段,数据类型是数字;还有一个创建日期CreateDate字段,数据类型是日期与时间。如下图。
然后填写好数据,所需的数据如下,这一章的内容都使用这些数据。其中蓝色的数据是以前的。
StudentID |
StudentName |
PhoneNo |
Age |
CreateDate |
123456 |
林则徐 |
13888080088 |
21 |
2015/9/25 |
562893 |
叶剑英 |
13920171101 |
15 |
2015/7/13 |
662356 |
黄飞鸿 |
13427103456 |
18 |
2015/9/4 |
785714 |
黄飞鸿 |
13978569013 |
12 |
2015/9/7 |
736375 |
霍金 |
13739475815 |
23 |
2015/8/13 |
284626 |
乔布斯 |
18382195632 |
22 |
2015/6/19 |
563992 |
陆逊 |
13795720163 |
19 |
2015/8/21 |
318264 |
乔森 |
15843956272 |
13 |
2015/5/30 |
248369 |
欧阳峰 |
19472747288 |
16 |
2015/7/16 |
473610 |
爱因斯坦 |
13329177473 |
25 |
2015/9/4 |
现在,我们可以来查找年龄大于等于18岁的,就可以用如下的语句:
SELECT * FROM Student WHERE Age>=18
结果是显而易见的。sql语句的运行结果如下
其他比较符的用法也是一样的。而且还可以与上一章所说的关系连接词一同使用。
例如:要查询15岁(包括)到21岁(不包括)之间的人,sql可以这样写:
SELECT * FROM Student WHERE Age>=15 AND Age<21
查询结果如下:
基于范围的搜索(1)
上面要查询查询15岁(包括)到21岁(不包括)之间的人,如果两个数值都是包括的,我们就可以使用BETWEEN…AND语句来实现。其基本语法是
SELECT* FROM Student WHERE 字段名 BETWEEN数值1 AND 数值2
BETWEEN…AND语句相当于是下面的语句:
SELECT* FROM Student WHERE 字段名>=数值1 AND 字段名<=数值2
我们还可以在BETWEEN前面加NOT,来表示不在此范围内。必须注意的是,加了NOT之后,两个数值都是不包括的。如果加了NOT,就相当于下面的语句:
SELECT* FROM Student WHERE 字段名<数值1 AND 字段名>数值2
可以写一下NOT的语句检验一下。如下:
SELECT * FROM Student WHERE Age NOT BETWEEN 15 AND 21
结果如下图所示,可以发现15和21的都没有出现在结果当中。而没有NOT的情况则交给读者自己去验证了。
基于范围的搜索(2)
多个OR逻辑连接词连接起来的条件可以用更简单的方法来表示。现在先来温习一下OR逻辑连接词。例如现在需要电话号码是19472747288(欧阳锋),或15843956272(乔森),或17639284669,或18856350376的人。后面专门加了2个数据中没有对应的人的电话。现在来看一下用OR逻辑连接词如何书写sql语句:
SELECT * FROM Student WHERE PhoneNo=19472747288 OR PhoneNo =15843956272 OR PhoneNo=17639284669 OR PhoneNo=18856350376
语句执行的结果当然是欧阳锋和乔森这两个人的记录显示出来。然而,这样的sql语句非常冗长,PhoneNo重复出现好多次,看起来也不好看。所以我们可以使用IN语句来实现。
IN语句的基本语法是:
SELECT* FROM Student WHERE 字段名 IN(值1,值2,值3……)
这个语法的值1,值2……不要求是数值,BETWEEN…AND之所以强调是数值,是因为只有数值才有大小的比较,但是IN代表的是字段的数据与值1,或值2,或值3……相等,所以既然是相等的话,任何数据都是可以的。
(值1,值2,值3)构成了一个范围,与BETWEEN…AND语句不同的是,这个范围不是连续的,而是分立的。所以,上面用OR连接词书写的语句就可以写成:
SELECT * FROM Student WHERE PhoneNo IN(19472747288,15843956272,17639284669,8856350376)
当前的代码显得更加清晰,写起来也不那么麻烦了。正如我所给出的四个电话号码中,最后的两个是数据中没有对应的人的电话号码,既然是搜索就存在搜索不到的问题,所以这个范围不一定全都是有效的(在数据中存在的)值,也就是说当前的记录中不会有任何记录的电话号码匹配最后这两个值。
模糊搜索
这里的模糊搜索,准确的称呼应该是模式匹配。实际上很多人都在其他的软件中使用过这样的搜索。例如,我们要找出全部姓“黄”的人。这样的需要是常有的。在sql中可以用LIKE关键字提出一个模糊搜索。基本的语法如下:
SELECT* FROM Student WHERE 字段名 LIKE ‘匹配字符串’
与此前的语法不同,匹配字符串中并没有给出完整的搜索条件,而是使用通配符代替了不确定的部分。例如找出全部姓“黄”的人,sql语句如下:
SELECT * FROM Student WHERE 字段名 LIKE ‘黄*’
注意模糊搜索单引号是必须的!而上面的语句中“*”就是通配符,表示任意个字符。所以’黄*’这个匹配字符串的意思是开头第一个字是黄,后面有多少个字,是什么字都随便。
匹配类型 |
模式 |
匹配举例(返回 True) |
不匹配举例 (返回 False) |
多个字符 |
a*a |
aa、aBa 和 aBBBa |
aBC |
|
*ab* |
abc、AABB 和 Xab |
aZb 和 bac |
|
ab* |
abcdefg 和 abc |
cab 和 aab |
特殊字符 |
a[*]a |
a*a |
aaa |
单个字符 |
a?a |
aaa、a3a 和 aBa |
aBBBa |
单个数字 |
a#a |
a0a、a1a 和 a2a |
aaa 和 a10a |
字符范围 |
[a-z] |
f、p 和 j |
2 和 & |
范围之外 |
[!a-z] |
9、& 和 % |
b 和 a |
数字值 |
[0-9] |
0,1,9 |
A、a、& 和 ~ |
非数字值 |
[!0-9] |
A、a、& 和 ~ |
0,9 |
复合值 |
a[!b-m]# |
An9、az0 和 a99 |
abc 和 aj0 |
这里解释一下最后的复合值。第一个字符是a,固定的。但是可以发现,在匹配举例的第一个An9,字母“a”是大写的,这证明LIKE是不识别大小写的,大小写按照同一个字符识别。然后[!b-m]是指不在b到m(即不是b、c、d、e、f、g、h、i、j、k、l、m)这12个字母的其他字符。需要注意的是a99也是匹配的,那就意味着不在b-m里指的是除了那12个字母之外的一切符号都是成立的,不仅限于字母。最后的#是一位的数字。
再举个例子,我们要寻找StudentID尾数是25,26的两个人(在数据中确实存在),可以这样写sql语句:
SELECT * FROM Student WHERE StudentID LIKE '####25' OR StudentID LIKE '####26'
两个匹配字符串的前四位都是#,表示前4个数字(目前的StudentID共6位)任意,然后后面给出来的25,26就是确定的。
搜索结果如下图所示:
这一节,先不给出代码,也先不用在VB运行,直接在Access执行sql语句观察效果即可。随着字段的增多,光使用ListBox已经不能满足我们的需要。在第九章,我将会讲述控件与数据库绑定,届时,我们将可以用表格控件完整呈现所有数据。同时还可以让ListBox自己更新数据库中的某个字段的内容,而不是使用ListBox的AddItem方法将Select返回的数据逐个添加到ListBox中。
在此布置一项作业吧。将上面的语句改成这样
SELECT* FROM Student WHERE StudentID LIKE '###25' OR StudentID LIKE '####26'。
25前面只有3个“#”,看看运行之后的结果是怎么样的。
参考文献:
[1] https://msdn.microsoft.com/zh-cn/library/office/ff195752(v=office.15).aspx