6.1 比较查询
在WHERE子句中可以使用比较运算符对数值、字符值等信息进行查询。比较运算符这里归纳为三类:算术比较运算符、BETWEEN...AND运算符和IN运算符。这一节将分别对这三种比较运算符的查询方法进行介绍。最后还将介绍WHERE子句中字符串和时间的比较方法。
6.1.1 算术比较运算符
SQL语句中的算术比较运算符主要包括=(等于)、>=(大于等于)、<=(小于等于)、>(大于)、<(小于)、!=(不等于)、<>(不等于)、!>(不大于)、!<(不小于)。在SELECT语句的WHERE子句中可以使用算术比较运算符对指定列进行比较,其语法格式如下:
字段1比较运算符 值
其中,字段1表示数据表中需要查询的字段列名,字段1后面跟的是算术比较运算符,值表示的是指定列要比较的数值。使用比较运算符返回的结果是一个逻辑值。如果逻辑值为TRUE,则会返回查询到的记录,如果逻辑值为FALSE,则不会返回相应的查询结果。
说明 在Microsoft SQL Server数据库中,使用“<>”符号表示不等于运算。
例6.1 查询课程表中课程学分>=4的课程信息。
SELECT curName,credit FROM T_curriculum WHERE credit>=4
其中,curName表示课程的名字,credit表示课程的学分。在WHERE子句中使用>=(大于等于)运算符将课程表中课程学分>=4的课程信息查询出来。其查询结果如图6.1所示。
图6.1 查询课程表中课程学分>=4的课程信息
在这个查询结果中,符合查询条件的记录一共有4条。从这4条记录中可以看到,这4门课程对应的学分数都大于或者等于4。下面再看一个在字符值中使用比较运算符的例子。
例6.2 查询教师信息表中教师职称不是教授的教师信息。
SELECT teaID,teaName,dept,profession
FROM T_teacher
WHERE profession!='教授'
其中teaID表示教师编号,teaName表示教师的姓名,dept表示教师所在的部门,profession表示教师的职称。在WHERE子句中使用!=(不等于)运算符查询教师信息表中教师职称不是教授的教师信息。其查询结果如图6.2所示。
图6.2 查询教师信息表中教师职称不是教授的教师信息
在这个查询结果中,符合查询条件的记录一共有4条。从上面的两个例子可以看出,在使用比较运算符执行SQL语句操作时,比较运算符的左侧和右侧的数据类型是可以相互兼容的。
例如在例6.1中WHERE子句的查询条件是课程学分>=4,这里的课程学分在数据表中定义的就是一个整数,在例6.2中WHERE子句的查询条件是profession!='教授',这里的教师职称在教师信息表中定义的是字符类型。也就是说,在使用比较运算符时,不能让一个字符类型的数据进行类似大于或者小于一个整型数据的比较。例如下面的语句是完全错误的。
profession>=4
因为profession是一个字符类型,而4是一个整型,这两个数据类型是不能相互兼容的,也没有任何的可比性。当然,这种写法本身也违背了SQL的语法规则。
注意 在SQL语句中,如果在WHERE子句中比较的是数值型数据,则可以不使用单引号(例如,例6.1);如果在WHERE子句中比较的是其他的数据类型(例如,字符串、日期型等)则必须使用单引号将其引住(例如,例6.2)。另外,WHERE子句中比较运算符的左侧和右侧的数据类型必须是类型兼容的。
提示 在SQL语句中提供了两个比较运算符来描述不等于运算。分别是!=(不等于)和<>(不等于),这两个运算符在使用时并没有太大的区别,可以互换使用。读者可以使用<>(不等于)运算符来重新执行一次例6.2,看一下查询的运行结果。
6.1.2 BETWEEN...AND运算符查询指定条件范围的记录
BETWEEN...AND运算符可以用来查询指定条件范围的记录。使用BETWEEN...AND运算符查询时在BETWEEN运算符和AND运算符后面都需要给定一个值。其语法格式如下:
字段1 BETWEEN 值1 AND 值2
其中,字段1表示数据表中需要查询的字段;值1为给定数值中较小的值;值2为给定数值中较大的值。其最终查询的结果也包括值1和值2本身的值。来看下面这个例子。
例6.3 查询教师信息表中年龄在30~50岁之间的教师信息。
SELECT teaID,teaName,age,sex,dept,profession FROM T_teacher WHERE age BETWEEN 30 AND 50
其中teaID表示教师编号,teaName表示教师的姓名,age表示教师年龄,sex表示教师性别,dept表示教师所在的部门,profession表示教师的职称。WHERE子句中指定了要查询教师的年龄范围是在30~50岁之间。其查询结果如图6.3所示。
图6.3 查询教师信息表中年龄在30~50岁之间的教师信息
这条SQL语句是从教师信息表中将教师年龄在30~50岁之间(包括30岁和50岁)的教师信息全都查询了出来。从查询的结果中可以看到,使用BETWEEN...AND运算符查询指定条件范围的记录时,其查询结果与age>=30 AND age<=50中得到结果相同。
提示 在SQL语句中使用BETWEEN...AND运算符可以查询指定条件范围的记录,也可以使用NOT BETWEEN...AND运算符来排除一些记录。例如如果要查询教师信息表中年龄不在30~50岁范围之间的教师信息,就可以使用NOT BETWEEN...AND运算符来完成。读者可以试着自己来完成这个SQL语句。
6.1.3 IN运算符查询与列表匹配的记录
IN运算符用来查询与列表匹配的记录。使用IN运算符,可以将满足列表中满足指定表达式的任何一个值都查询出来。IN运算符后的属性值可以是一个,也可以有多个,多个属性值之间需要用逗号分隔。其语法格式如下:
字段1 IN(属性值1, 属性值2, 属性值3...)
其中字段1表示数据表中需要查询的字段;属性值1, 属性值2, 属性值3分别表示需要查询的值。属性值既可以是数字类型的也可以是字符类型的。如果属性值是字符类型的值,则需要使用单引号将其引住。
例6.4 查询教师信息表中教师所在部门为计算机系或者数学系的所有教师信息。
SELECT teaID,teaName,age,sex,dept,profession FROM T_teacher WHERE dept IN('计算机系','数学系')
WHERE子句中的IN运算符后面的括号中指定要查询的是计算机系或者数学系的所有教师信息。其查询结果如图6.4所示。
图6.4 查询教师信息表中教师所在部门为计算机系和数学系的所有教师信息
这条SQL语句是从数据表中选择教师所在部门为计算机系或者数学系的教师信息,如果在教师信息表中有计算机系或者数学系,就将其查询结果所在的行返回。在这个查询结果中,符合查询条件的记录一共有6条。这6条记录包括了部门为计算机系和数学系的所有教师信息。
提示 在SQL语句中可以使用IN运算符查询与列表匹配的记录,也可以使用NOT IN运算符来排除一些记录。例如如果要查询教师信息表中不在计算机系或者数学系的所有教师信息,就可以使用NOT IN运算符来完成。读者可以试着自己来完成这个SQL语句。
使用IN运算符的查询语句可以用等号运算符和OR运算符(参看6.2.2小节)来替代,其查询结果是相同的。例如例6.4可以使用下面的SQL语句替换。
SELECT teaID,teaName,age,sex,dept,profession FROM T_teacher WHERE dept='计算机系' OR dept='数学系'
这个SQL语句中,将IN运算符的查询语句用OR运算符取代,但是如果需要查询的记录满足多个任一条件时,使用OR运算符SQL语句就不是很容易阅读。试想一下,如果要查询教师信息表中所在部门在计算机系、数学系、物理系、机械系的教师信息,使用OR运算符SQL语句书写起来可能就会比较烦琐,不如使用IN运算符的SQL语句简练和容易阅读。
6.1.4 字符串比较
在使用SQL语句进行比较查询时,经常会遇到字符串比较问题。对字符串进行比较时,常用的数据库都可以使用比较运算符对字符串进行比较,另外,在MySQL数据库中还可以使用关键字BINARY对字符串进行二进制比较。在这一小节中将对这两种字符串比较方式进行介绍。
1. 使用比较运算符对字符串进行比较
在使用比较运算符比较字符值时,比较运算符中左右两侧的字符值应该用单引号将该字符引住。下面来看一个使用比较运算符对字符串进行比较的例子。
例6.5 使用比较运算符对字符串进行比较。
SELECT 'sql5.0'>'sql'
这条SELECT语句是对字符串sql5.0和字符串sql进行比较,这里使用大于运算符(>)对两个字符串进行比较,其比较的结果如下所示。
+--------------------------+ | 'sql5.0'>'sql'| +--------------------------+ | 1 |
其查询的结果为1,表示返回的结果为TRUE。即当在SELECT语句对指定的两个字符串进行比较时,认为字符串sql5.0确实比字符串sql大。
说明 在使用比较运算符对字符进行查询和比较时,有的数据库需要区分字符的大小写,例如, Oracle数据库等。有的数据库对字符进行查询和比较时不区分字符的大小写,例如,Microsoft SQL Server数据库和MySQL数据库等。为了避免由于不注意字符的大小写区分而查询不到正确的结果,可以使用将字符串全部转换为大写的UPPER函数和字符串全部转换为小写的LOWER函数对字符进行大小写转换,有关这一部分内容将在10.1.2和10.1.3节中介绍。
在MySQL数据库中,对字符串的比较一般不区分大小写。例如下面这条SELECT语句。
SELECT 'mysql'='MySQL'
这条SELECT语句是对字符串mysql和字符串MySQL进行比较,由于MySQL数据库中对字符串的比较对字母的大小写不敏感,因此在使用等号运算符对这两个字符串进行比较时,数据库会认为这两个字符串是相等的,其查询的结果如下所示。
+--------------------------+ | 'mysql'='MySQL'| +--------------------------+ | 1 |
可以看到,查询的结果为1,表示返回的结果为TRUE。即当在SELECT语句对指定的两个字符串进行比较时,并不对字符串中字母的大小写进行区分。
2. 使用BINARY关键字对字符串进行二进制比较
如果希望比较的字符串区分大小写,可以使用关键字BINARY对字符串进行二进制比较。使用BINARY关键字,会把一个字符串(或者一个数字)转换为一个二进制的对象。
使用BINARY关键字对字符串进行二进制比较有两种语法格式,这两种语法格式是等价的。其语法格式如下:
SELECT string1 比较运算符 BINARY string2 SELECT BINARY string1 比较运算符 string2
其中,string1和string2表示要比较的两个字符串;比较运算符可以是=(等于)、>=(大于等于)、<=(小于等于)、>(大于)、<(小于)、!=(不等于)、<>(不等于)、!>(不大于)、!<(不小于);BINARY是关键字,用来告诉数据库管理系统,需要对字符串进行二进制的比较。
下面通过一个例子来看一下使用BINARY关键字对字符串进行二进制比较时,查询的结果会有什么不同。
例6.6 使用BINARY关键字对字符串进行二进制比较。
SELECT 'mysql' = BINARY 'MySQL'
这条SELECT语句是对字符串mysql和字符串MySQL进行二进制比较,因为这段SQL语句中多了一个BINARY关键字,其查询的结果如下所示。
+--------------------------+----------+ | 'mysql' = BINARY 'MySQL''| +--------------------------+---------+ | 0 |
可以看到,查询的结果为0,表示返回的结果为FALSE。即当在SELECT语句对指定的两个字符串进行二进制比较时,对字符串中字母的大小写进行了区分。
6.1.5 日期时间的比较
在WHERE子句中对日期值和时间进行比较时,要比较的日期和时间必须是数据库服务器可以接受的字符串格式。例如,在学生信息表(T_student)中,学生的出生日期被设置为DATETIME日期类型的变量。要想在WHERE子句中对学生的出生日期值进行比较,可以使用单引号将该日期值引住。下面来看一个日期值比较的例子。
例6.7 查询学生信息表中出生日期在1986年01月01日之后的学生信息。
SELECT stuID ,stuName,age,sex,birth FROM T_student WHERE birth >'19860101'
这段SQL语句是查询学生信息表中出生日期在1986年01月01日之后的学生信息。在WHERE子句中给出了一个限定日期值的查询条件,其查询结果如图6.5所示。
图6.5 查询学生信息表中出生日期在1986年01月01日之后的学生信息
从显示的结果可以看到,MySQL 5.0数据库中,日期类型的变量在数据库中是以年-月-日 时∶分∶秒的形式显示的。
注意 比较日期值和时间时需要使用单引号将其引住。
除了可以使用算术比较运算符对日期进行比较以外,也可以使用BETWEEN...AND运算符来查询指定某一个时间范围的记录。例如要查询出生日期的起始时间在1986年01月01日,终止时间在1988年12月12日的全体学生的记录,使用BETWEEN...AND运算符就可以这样写。
SELECT stuID ,stuName,age,sex,birth FROM T_student WHERE birth BETWEEN'19860101' AND '19881212'
说明 在Oracle数据库中,日期比较一种更好的方法是使用日期转换函数TO_DATE;在MySQL数据库中,则可以使用DATE_FORMAT函数。通过这些函数可以将日期类型的值转换为需要的形式。TO_DATE函数以及DATE_FORMAT函数的使用方法将在10.3.2节中介绍。