1、MySQL开发与实践 第5章 数据库的查询主要内容主要内容1.基本查询语句2.单表查询3.聚合函数查询4.连接查询5.子查询6.合并查询结果7.定义表和字段的别名8.使用正则表达式查询9.综合实例使用正则表达式查询学生成绩信息第第5 5章章 数据库的查询数据库的查询5.1 5.1 基本查询语句基本查询语句 SELECT语句是最常用的查询语句,它的使用方式有些复杂,但功能是相当强大的。SELECT语句的基本语法如下:select selection_list /要查询的内容,选择哪些列from 数据表名 /指定数据表where primary_constraint /查询时需要满足的条件,行必须
2、满足的条件group by grouping_columns /如何对结果进行分组order by sorting_cloumns /如何对结果进行排序having secondary_constraint/查询时满足的第二条limit count /限定输出的查询结果其中使用的子句将在后面逐个介绍。下面先介绍SELECT语句的简单应用。(1)使用SELECT语句查询一个数据表使用SELECT语句时,首先要确定所要查询的列。“*”代表所有的列。例如:查询db_database06数据库user表中的所有数据,代码如下:mysql use db_database06Database change
3、dmysql select*from user;+-+-+-+-+|id|user|lxdh|jtdz|+-+-+-+-+|1|mr|12345678|长春市|2|mrsoft|87654321|四平市|+-+-+-+-+2 rows in set(0.00 sec)这是查询整个表中所有列的操作,还可以针对表中的某一列或多列进行查询。(2)查询表中的一列或多列 针对表中的多列进行查询,只要在select后面指定要查询的列名即可,多列之间用“,”分隔。例如:查询user表中的id和lxdh,代码如下:mysql select id,lxdh from user;+-+-+|id|lxdh|+-+
4、-+|1|12345678|2|87654321|+-+-+2 rows in set(0.00 sec)(3)从一个或多个表中获取数据 使用SELECT语句进行查询,需要确定所要查询的数据在哪个表中,或在哪些表中,在对多个表进行查询时,同样使用“,”对多个表进行分隔。【例例5-15-1】从tb_admin表和tb_students表中查询出tb_admin.id、tb_admin.tb_user、tb_students.id和tb_students.name字段的值。其代码如下:mysql select tb_admin.id,tb_admin.tb_user,tb_students.id,
5、tb_students.name fromtb_admin,tb_students;+-+-+-+-+|id|tb_user|id|name|+-+-+-+-+|1|mr|1|潘攀|2|明日科技|1|潘攀|+-+-+-+-+2 rows in set(0.03 sec)说明:在查询数据库中的数据时,如果数据中涉及到中文字符串,有可能在输出时会出现乱码。那么最后在执行查询操作之前,通过set names 语句设置其编码格式,然后再输出中文字符串时就不会出现乱码了。如上例中所示,应用set names 语句设置其编码格式为gb2312。还可以在WHERE子句中使用连接运算来确定表之间的联系,然后根
6、据这个条件返回查询结果。例如:从家庭收入表(jtsr)中查询出指定用户的家庭收入数据,条件是用户的ID为1。其代码如下:mysql select jtsr from user,jtsr -where user.user=jtsr.user and user.id=1;+-+|jtsr|+-+|10000|+-+2 rows in set(0.00 sec)其中,user.user=jtsr.user将表user和jtsr连接起来,叫做等同连接;如果不使用user.user=jtsr.user,那么产生的结果将是两个表的笛卡尔积,叫做全连接。5.2.1 查询所有字段5.2.2 查询指定字段5.2
7、.3 查询指定数据5.2.4 带IN关键字的查询5.2.5 带BETWEEN AND的范围查询5.2.6 带LIKE的字符匹配查询5.2.7 用IS NULL关键字查询空值5.2.8 带AND的多条件查询5.2.9 带OR的多条件查询5.2.10 用DISTINCT关键字去除结果中的重复行5.2.11 用ORDER BY关键字对查询结果排序5.2.12 用GROUP BY关键字分组查询5.2.13 用LIMIT限制查询结果的数量5.2 5.2 单表查询单表查询 查询所有字段是指查询表中所有字段的数据。这种方式可以将表中所有字段的数据都查询出来。在MySQL中可以使用“*”代表所有的列,即可查出
8、所有的字段,语法格式如下:SELECT*FROM 表名;其应用已经在5.1基本查询语句中领教过,这里不再赘述。5.2.1 5.2.1 查询所有字段查询所有字段查询指定字段可以使用下面的语法格式:SELECT 字段名 FROM 表名;如果是查询多个字段,可以使用“,”对字段进行分隔。【例例5-25-2】查询db_database06数据库tb_login表中“user”和“pwd”两个字段,SELECT查询语句如下:SELECT user,pwd FROM tb_login;查询结果如图5-1所示。图5-1 查询指定字段的数据5.2.2 5.2.2 查询指定字段查询指定字段 如果要从很多记录中查
9、询出指定的记录,那么就需要一个查询的条件。设定查询条件应用的是WHERE子句。通过它可以实现很多复杂的条件查询。在使用WHERE子句时,需要使用一些比较运算符来确定查询的条件。其常用比较运算符如表5-1所示。表5-1 比较运算符表5-1中列举的是WHERE子句常用的比较运算符,例中的id是记录的编号,name是表中的用户名。5.2.3 5.2.3 查询指定数据查询指定数据运 算 符名 称示 例运 算 符名 称示 例=等于Id=5Is not nulln/aId is not null大于Id5Betweenn/aId between1 and 15小于Id大于等于Id=5Not inn/aNa
10、me not in(shi,li)=小于等于Id=5Like模 式 匹配Name like(shi%)!=或不等于Id!=5N o t like模 式 匹配N a m e n o t l i k e(shi%)Is nulln/aId is nullRegexp 常 规 表达式Name正则表达式【例例5-35-3】应用where子句,查询tb_login表,条件是user(用户名)为mr,代码如下:select*from tb_login where user=mr;查询结果如图5-2所示。图5-2 查询指定数据IN关键字可以判断某个字段的值是否在于指定的集合中。如果字段的值在集合中,则满足查
11、询条件,该记录将被查询出来;如果不在集合中,则不满足查询条件。其语法格式如下:SELECT*FROM 表名 WHERE 条件 NOT IN(元素1,元素2,元素n);p “NOT”是可选参数,加上NOT表示不在集合内满足条件;p“元素”表示集合中的元素,各元素之间用逗号隔开,字符型元素需要加上单引号。【例例5-45-4】应用IN关键字查询tb_login表中user字段为mr和lx的记录,查询语句如下:SELECT*FROM tb_login WHERE user IN(mr,lx);查询结果如图5-3所示。图5-3 使用IN关键字查询5.2.4 5.2.4 带带ININ关键字的查询关键字的查
12、询【例例5-55-5】使用NOT IN关键字查询tb_login表中user字段不为mr和lx的记录,查询语句如下:SELECT*FROM tb_login WHERE user NOT IN(mr,lx);查询结果如图5-4所示。图5-4 使用NOT IN关键查询 BETWEEN AND关键字可以判断某个字段的值是否在指定的范围内。如果字段的值在指定范围内,则满足查询条件,该记录将被查询出来。如果不在指定范围内,则不满足查询条件。其语法如下:SELECT*FROM 表名 WHERE 条件 NOT BETWEEN 取值1 AND 取值2;pNOT:是可选参数,加上NOT表示不在指定范围内满足条
13、件;p取值1:表示范围的起始值;p取值2:表示范围的终止值。【例例5-65-6】查询tb_login表中id值在57之间的数据,查询语句如下:SELECT*FROM tb_login WHERE id BETWEEN 5 AND 7;查询结果如图5-5所示。图5-5 使用BETWEEN AND关键字查询 如果要查询tb_login表中id值不在57之间的数据,则可以通过NOT BETWEEN AND来完成。其查询语句如下:SELECT*FROM tb_login WHERE id NOT BETWEEN 5 AND 7;5.2.5 5.2.5 带带BETWEEN ANDBETWEEN AND的
14、范围查询的范围查询 LIKE属于较常用的比较运算符,通过它可以实现模糊查询。它有两种通配符:“%”和下划线“_”:p“%”可以匹配一个或多个字符,可以代表任意长度的字符串,长度可以为0。例如,“明%技”表示以“明”开头,以“技”结尾的任意长度的字符串。该字符串可以代表明日科技、明日编程科技、明日图书科技等字符串。p“_”只匹配一个字符。例如,m_n表示以m开头,以n结尾的3个字符。中间的“_”可以代表任意一个字符。说明:字符串“p”和“入”都算做一个字符,在这点上英文字母和中文是没有区别的。5.2.6 5.2.6 带带LIKELIKE的字符匹配查询的字符匹配查询【例例5-75-7】查询tb_l
15、ogin表中user字段中包含mr字符的数据,查询语句如下:select*from tb_login where user like%mr%;查询结果如图5-6所示。图5-6 模糊查询 IS NULL关键字可以用来判断字段的值是否为空值(NULL)。如果字段的值是空值,则满足查询条件,该记录将被查询出来。如果字段的值不是空值,则不满足查询条件。其语法格式样如下:IS NOT NULL其中,“NOT”是可选参数,加上NOT表示字段不是空值时满足条件。【例例5-85-8】下面使用IS NULL关键字查询db_database06数据库的tb_book表中name字段的值为空的记录,查询语句如下:S
16、ELECT books,row FROM tb_book WHERE row IS NULL;查询结果如图5-7所示。图5-7 查询tb_book表中row字段值为空的记录5.2.7 5.2.7 用用IS NULLIS NULL关键字查询空值关键字查询空值 AND关键字可以用来联合多个条件进行查询。使用AND关键字时,只有同时满足所有查询条件的记录会被查询出来。如果不满足这些查询条件的其中一个,这样的记录将被排除掉。AND关键字的语法格式如下:select*from 数据表名 where 条件1 and 条件2 AND 条件表达式n;AND关键字连接两个条件表达式,可以同时使用多个AND关键字
17、来连接多个条件表达式。【例例5-95-9】下面查询tb_login表中user字段值为mr,并且section字段值为PHP的记录,查询语句如下:select*from tb_login where user=mr and section=php;查询结果如图5-8所示。图5-8 使用AND关键字实现多条件查询5.2.8 5.2.8 带带ANDAND的多条件查询的多条件查询 OR关键字也可以用来联合多个条件进行查询,但是与AND关键字不同,OR关键字只要满足查询条件中的一个,那么此记录就会被查询出来;如果不满足这些查询条件中的任何一个,这样的记录将被排除掉。OR关键字的语法格式如下:selec
18、t*from 数据表名 where 条件1 OR 条件2 OR 条件表达式n;OR可以用来连接两个条件表达式。而且,可以同时使用多个OR关键字连接多个条件表达式。【例例5-105-10】下面查询tb_login表中section字段的值为“PHP”或者“程序开发”的记录,查询语句如下:select*from tb_login where section=php or section=程序开发;查询结果如图5-9所示。图5-9 使用OR关键字实现多条件查询5.2.9 5.2.9 带带OROR的多条件查询的多条件查询使用DISTINCT关键字可以去除查询结果中的重复记录,语法格式如下:select
19、 distinct 字段名 from 表名;【例例5-115-11】下面使用distinct关键字去除tb_login表中name字段中的重复记录,查询语句如下:select distinct name from tb_login;查询结果如图5-10所示。去除重复记录前的name字段值如图5-11所示。图5-10 使用DISTINCT关键字去除结果中的重复行 图5-11 去除重复记录前的name字段值5.2.10 5.2.10 用用DISTINCTDISTINCT关键字去除结果关键字去除结果中的重复行中的重复行 使用ORDER BY可以对查询的结果进行升序(ASC)和降序(DESC)排列,在
20、默认情况下,ORDER BY按升序输出结果。如果要按降序排列可以使用DESC来实现。语法格式如下:ORDER BY 字段名 ASC|DESC;pASC表示按升序进行排序;pDESC表示按降序进行排序。说明:如果对含有NULL值的列进行排序时,如果是按升序排列,NULL值将出现在最前面,如果是按降序排列,NULL值将出现在最后。5.2.11 5.2.11 用用ORDER BYORDER BY关键字对查询结果排序关键字对查询结果排序 【例例5-125-12】查询tb_login表中的所有信息,按照“id”进行降序排列,查询语句如下:select*from tb_login order by id
21、desc;查询结果如图5-12所示。图5-12 按id序号进行降序排列 通过GROUP BY子句可以将数据划分到不同的组中,实现对记录进行分组查询。在查询时,所查询的列必须包含在分组的列中,目的是使查询到的数据没有矛盾。1使用GROUP BY关键字来分组单独使用GROUP BY关键字,查询结果只显示每组的一条记录。【例例5-135-13】使用GROUP BY关键字对tb_book表中talk字段进行分组查询,查询语句如下:select id,books,talk from tb_book GROUP BY talk;查询结果如图5-13所示。图5-13 使用GROUP BY关键进行分组查询5.
22、2.12 5.2.12 用用GROUP BYGROUP BY关键字分组查询关键字分组查询为了使分组更加直观明了,下面查询tb_book表中的记录,查询结果如图5-14所示。图5-14 tb_book表中的记录2GROUP BY关键字与GROUP_CONCAT()函数一起使用使用GROUP BY关键字和GROUP_CONCAT()函数查询,可以将每个组中的所有字段值都显示出来。【例例5-145-14】下面使用GROUP BY关键字和GROUP_CONCAT()函数对tb_book表中的talk字段进行分组查询,查询语句如下:select id,books,GROUP_CONCAT(talk)fr
23、om tb_book GROUP BY talk;查询结果如图5-15所示。图5-15 使用GROUP BY关键字与GROUP_CONCAT()函数进行分组查询3按多个字段进行分组使用GROUP BY关键字也可以按多个字段进行分组。【例例5-155-15】下面对tb_book表中的user字段和sort字段进行分组,分组过程中,先按照talk字段进行分组。当talk字段的值相等时,再按照sort字段进行分组,查询语句如下:select id,books,talk,user from tb_book GROUP BY user,talk;查询结果如图5-16所示。图5-16 使用GROUP BY
24、关键字实现多个字段分组 查询数据时,可能会查询出很多的记录。而用户需要的记录可能只是很少的一部分。这样就需要来限制查询结果的数量。LIMIT是MySQL中的一个特殊关键字。LIMIT子句可以对查询结果的记录条数进行限定,控制它输出的行数。下面通过具体实例来了解Limit的使用方法。【例例5-165-16】查询tb_login表中,按照id编号进行升序排列,显示前3条记录,查询语句如下:select*from tb_login order by id asc limit 3;查询结果如图5-17所示。图5-17 使用limit关键字查询指定记录数 使用LIMIT还可以从查询结果的中间部分取值。首
25、先要定义两个参数,参数1是开始读取的第一条记录的编号(在查询结果中,第一个结果的记录编号是0,而不是1);参数2是要查询记录的个数。5.2.13 5.2.13 用用LIMITLIMIT限制查询结果的数量限制查询结果的数量【例例5-175-17】查询tb_login表中,按照id编号进行升序排列,从编号1开始,查询两条记录,查询语句如下:select*from tb_login where id order by id asc limit 1,2;查询结果如图5-18所示。图5-18 使用limit关键字查询指定记录5.3 5.3 聚合函数查询聚合函数查询5.3.1 COUNT()函数5.3.2
26、 SUM()函数5.3.3 AVG()函数5.3.4 MAX()函数5.3.5 MIN()函数 COUNT()函数,对于除“*”以外的任何参数,返回所选择集合中非NULL值的行的数目;对于参数“*”,返回选择集合中所有行的数目,包含NULL值的行。没有WHERE子句的COUNT(*)是经过内部优化的,能够快速的返回表中所有的记录总数。【例例5-185-18】下面使用count()函数统计tb_login表中的记录数,查询语句如下:select count(*)from tb_login;查询结果如图5-19所示。结果显示,tb_login表中共有4条记录。图5-19 使用count()函数统计
27、记录数5.3.1 COUNT()5.3.1 COUNT()函数函数5.3.2 SUM()5.3.2 SUM()函数函数SUM()函数可以求出表中某个字段取值的总和。【例例5-195-19】使用SUM()函数统计tb_book表中图书的访问量字段(row)的总和。在查询前,先来查询一下tb_book表中row字段的值,结果如图5-20所示。图5-20 tb_book表中row字段的值下面使用SUM()函数来查询。查询语句如下:select sum(row)from tb_book;查询结果如图5-21所示。结果显示row字段的总和为116。图5-21 使用SUM()函数查询row字段值的总和 A
28、VG()函数可以求出表中某个字段取值的平均值。【例例5-205-20】下面使用AVG()函数求tb_book表中row字段值的平均值,查询语句如下:select AVG(row)from tb_book;查询结果如图5-22所示。图5-22 使用AVG()函数求row字段值的平均值5.3.3 AVG()5.3.3 AVG()函数函数5.3.4 MAX()5.3.4 MAX()函数函数MAX()函数可以求出表中某个字段取值的最大值。【例例5-215-21】下面使用MAX()函数查询tb_book表中row字段的最大值,查询语句如下:select MAX(row)from tb_book;查询结果
29、如图5-23所示。图5-23 使用MAX()函数求row字段的最大值 下面来看一下tb_book表中row字段的所有值,查询结果如图5-24所示。结果显示row字段中最大值为95,与使用MAX函数查询的结果一致。图5-24 tb_book表中row字段的所有值5.3.5 MIN()5.3.5 MIN()函数函数MIN()函数可以求出表中某个字段取值的最小值。【例例5-225-22】使用MIN()函数查询tb_book表中row字段的最小值,查询语句如下:select MIN(row)from tb_book;查询结果如图5-25所示。图5-25 使用MIN()函数求row字段的最小值5.4 5
30、.4 连接查询连接查询5.4.1 内连接查询5.4.2 外连接查询5.4.3 复合条件连接查询5.4.1 5.4.1 内连接查询内连接查询 内连接是最普遍的连接类型,而且是最匀称的,因为它们要求构成连接的每一部分的每个表的匹配,不匹配的行将被排除。内连接的最常见的例子是相等连接,也就是连接后的表中的某个字段与每个表中的都相同。这种情况下,最后的结果集只包含参加连接的表中与指定字段相符的行。【例例5-235-23】下面有两个表,tb_login用户信息表和tb_book图书信息表,先来分别看下各表的数据,图5-26为tb_login表的数据,图5-27为tb_book表的数据。图5-26 tb_
31、login数据表图5-27 tb_book数据表 从上面的查询结果中可以看出,在两个表中存在一个连接user字段,它在两个表中是等同的,tb_login表的user字段与tb_book表的user字段相等,因此可以创建两个表的一个连接。查询语句如下:select name,books from tb_login,tb_book where tb_login.user=tb_book.user;查询结果如图5-28所示。图5-28 内连接查询5.4.2 5.4.2 外连接查询外连接查询与内连接不同,外连接是指使用OUTER JOIN关键字将两个表连接起来。外连接生成的结果集不仅包含符合连接条件的
32、行数据,而且还包括左表(左外连接时的表)、右表(右外连接时的表)或两边连接表(全外连接时的表)中所有的数据行。语法格式如下:SELECT 字段名称 FROM 表名1 LEFT|RIGHT JOIN 表名2 ON 表名1.字段名1=表名2.属性名2;外连接分为左外连接(LEFT JOIN)、右外连接(RIGHT JOIN)和全外连接3种类型。1左外连接左外连接(LEFT JOIN)是指将左表中的所有数据分别与右表中的每条数据进行连接组合,返回的结果除内连接的数据外,还包括左表中不符合条件的数据,并在右表的相应列中添加NULL值。【例例5-245-24】下面使用左外连接查询tb_login表和tb
33、_book表,通过user字段进行连接,查询语句如下:select section,tb_login.user,books,row from tb_login left join tb_book on tb_login.user=tb_book.user;查询结果如图5-29所示。图5-29 左外连接查询 结果显示,第1条记录的books和row字段的值为空,这是因为在tb_book表中并不存在user字段为mrkj的值。2右外连接 右外连接(RIGHT JOIN)是指将右表中的所有数据分别与左表中的每条数据进行连接组合,返回的结果除内连接的数据外,还包括右表中不符合条件的数据,并在左表的相应
34、列中添加NULL。【例例5-255-25】下面使用右外连接查询tb_book表和tb_login表,两表通过user字段连接,查询语句如下:select section,tb_book.user,books,row from tb_book right join tb_login on tb_book.user=tb_login.user;查询结果如图5-30所示。图5-30 右外连接查询5.4.3 5.4.3 复合条件连接查询复合条件连接查询 在连接查询时,也可以增加其他的限制条件。通过多个条件的复合查询,可以使查询结果更加准确。【例例5-265-26】下面使用内连接查询tb_book表和t
35、b_login表。并且tb_book表中row字段值必须大于5,查询语句如下:select section,tb_book.user,books,row from tb_book,tb_login where tb_book.user=tb_login.user and row5;查询结果如图5-31所示。图5-31 复合条件连接查询5.5 5.5 子查询子查询5.5.1 带IN关键字的子查询5.5.2 带比较运算符的子查询5.5.3 带EXISTS关键字的子查询5.5.4 带ANY关键字的子查询5.5.5 带ALL关键字的子查询5.5.1 5.5.1 带带ININ关键字的子查询关键字的子查询
36、 只有子查询返回的结果列包含一个值时,比较运算符才适用。假如一个子查询返回的结果集是值的列表,这时比较运算符就必须用IN运算符代替。IN运算符可以检测结果集中是否存在某个特定的值,如果检测成功就执行外部的查询。【例例5-275-27】下面查询tb_login表中的记录,但user字段值必须在tb_book表中的user字段中出现过,查询语句如下:select*from tb_login where user in(select user from tb_book);在查询前,先来分别看一下tb_login和tb_book表中的user字段值,以便进行对比,tb_login表中的user字段值如
37、图5-32所示。图5-32 tb_login表中的user字段值tb_book表中的user字段值如图5-33所示。图5-33 tb_book表中的user字段值 从上面的查询结果可以看出,在tb_book表的user字段中没有出现mrkj值。下面执行带IN关键字的子查询语句,查询结果如图5-34所示。图5-34 使用IN关键子实现子查询 查询结果只查询出了user字段值为lx和mr的记录,因为在tb_book表的user字段中没有出现mrkj的值。说明:NOT IN关键字的作用与IN关键字刚好相反。在本例中,如果将IN换为NOT IN,则查询结果将会只显示一条user字段值为mrkj的记录。
38、5.5.2 5.5.2 带比较运算符的子查询带比较运算符的子查询 子查询可以使用比较运算符。这些比较运算符包括=、!=、=、=(select row from tb_row where id=1);查询结果如图5.37所示。图5-37 使用比较运算符的子查询方式来查询访问量为“优秀”的图书信息5.5.3 5.5.3 带带EXISTSEXISTS关键字的子查询关键字的子查询 使用EXISTS关键字时,内层查询语句不返回查询的记录。而是返回一个真假值。如果内层查询语句查询到满足条件的记录,就返回一个真值(true),否则,将返回一个假值(false)。当返回的值为true时,外层查询语句将进行查询
39、;当返回的为false时,外层查询语句不进行查询或者查询不出任何记录。【例例5-295-29】下面使用子查询查询tb_book表中是否存在id值为27的记录,如果存在则查询tb_row表中的记录,如果不存在则不执行外层查询,查询语句如下:select*from tb_row where exists(select*from tb_book where id=27);查询结果如图5-38所示。图5-38 使用EXISTS关键字的子查询 因为子查询tb_book表中存在id值为27的记录,即返回值为真,外层查询接收到真值后,开始执行查询。当EXISTS关键与其他查询条件一起使用时,需要使用AND或
40、者OR来连接表达式与EXISTS关键字。【例例5-305-30】查询如果tb_row表中存在name值为“优秀”的记录,则查询tb_book表中row字段大于等于90的记录,查询语句如下:select id,books,row from tb_book where row=90 and exists(select*from tb_row where name=优秀);查询结果如图5-39所示。图5-39 使用EXISTS关键字查询tb_book表中row字段大于等于90的记录说明:NOT EXISTS与EXISTS刚好相反,使用NOT EXISTS关键字时,当返回的值是true时,外层查询语句
41、不执行查询;当返回值是false时,外层查询语句将执行查询。5.5.4 5.5.4 带带ANYANY关键字的子查询关键字的子查询 ANY关键字表示满足其中任意一个条件。使用ANY关键字时,只要满足内层查询语句返回的结果中的任意一个,就可以通过该条件来执行外层查询语句。【例例5-315-31】查询tb_book表中row字段的值小于tb_row表中row字段最小值的记录,首先查询出tb_row表中row字段的值,然后使用ANY关键字(“ANY”表示小于所有值)判断。查询语句如下:select books,row from tb_book where row=ALL”表示大于等于所有值)判断,查询
42、语句如下:select books,row from tb_book where row=ALL(select row from tb_row);查询结果如图5-43所示。图5-43 使用ALL关键字实现子查询 为了使结果更加直观,下面分别查询tb_book表和tb_row表中的row字段值,查询结果如图5-44、图5-45所示。图5-44 tb_book表中row字段的值 图5-45 tb_row表中row字段的值 结果显示,tb_row表中row字段的最大值为90,在tb_book表中row字段大于90的只有第2条记录95,与带ALL关键字的子查询结果相同。说明:ANY关键字和ALL关键字
43、的使用方式是一样的,但是这两者有很大的区别。使用ANY关键字时,只要满足内层查询语句返回的结果中的任何一个,就可以通过该条件来执行外层查询语句。而ALL关键字则需要满足内层查询语句返回的所有结果,才可以执行外层查询语句。5.6 5.6 合并查询结合并查询结 合并查询结果是将多个SELECT语句的查询结果合并到一起。因为某种情况下,需要将几个SELECT语句查询出来的结果合并起来显示。合并查询结果使用UNION和UNION ALL关键字。UNION关键字是将所有的查询结果合并到一起,然后去除相同记录;而UNION ALL关键字则只是简单的将结果合并到一起,下面分别介绍这两种合并方法。UNION【
44、例例5-335-33】下面查询tb_book表和tb_login表中的user字段,并使用UNION关键字合并查询结果。在执行查询操作前,先来看一下tb_book表和tb_login表中user字段的值,查询结果如图5-46、图5-47所示。图5-46 tb_book表中user字段的值 图5-47 tb_login表中user字段的值 结果显示,在tb_book表中user字段的值有两种,分别为mr和lx,而tb_login表中user字段的值有三种。下面使用UNION关键字合并两个表的查询结果,查询语句如下:select user from tb_bookUNIONselect user
45、from tb_login;查询结果如图5-48所示。结果显示,合并后将所有结果合并到了一起,并去除了重复值。图5-48 使用UNION关键字合并查询结果pUNION ALL 查询tb_book表和tb_login表中的user字段,并使用UNION ALL关键字合并查询结果,查询语句如下:select user from tb_bookUNION ALLselect user from tb_login;查询结果如图5-49所示。tb_book表和tb_login表的记录请参见上例。图5-49 使用UNION ALL关键字合并查询结果5.7 5.7 定义表和字段的别名定义表和字段的别名5.7
46、.1 为表取别名5.7.2 为字段取别名5.7.1 5.7.1 为表取别名为表取别名当表的名称特别长时,在查询中直接使用表名很不方便。这时可以为表取一个贴切的别名。【例例5-345-34】下面为tb_program表取别名为p,然后查询tb_program表中talk字段值为php的记录,查询语句如下:select*from tb_program p where p.talk=PHP;“tb_program p”表示tb_program表的别名为p;p.talk表示tb_program表中的talk字段。查询结果如图5-50所示。图5-50 为表取别名5.7.2 5.7.2 为字段取别名为字段
47、取别名 当查询数据时,MySQL会显示每个输出列的名词。默认情况下,显示的列名是创建表时定义的列名。我们同样可以为这个列取一个别名。MySQL中为字段取别名的基本形式如下:字段名 AS 别名【例例5-355-35】下面为tb_login表中的section和name字段分别取别名为login_section和login_name,SQL代码如下:select section AS login_section,name AS login_name from tb_login;查询结果如图5-51所示。图5-51 为字段取别名5.8 5.8 使用正则表达式查询使用正则表达式查询5.8.1 匹配指定
48、字符中的任意一个5.8.2 使用“*”和“+”来匹配多个字符5.8.1 5.8.1 匹配指定字符中的任意一个匹配指定字符中的任意一个 使用方括号()可以将需要查询字符组成一个字符集。只要记录中包含方括号中的任意字符,该记录将会被查询出来。例如,通过“abc”可以查询包含a、b和c等3个字母中任何一个的记录。【例例5-365-36】下面从info表name字段中查询包含c、e和o3个字母中任意一个的记录。SQL代码如下:SELECT*FROM info WHERE name REGEXP ceo;代码执行结果如下:图5-52 匹配指定字符中的任意一个5.8.2 5.8.2 使用使用“*”和和“+
49、”来匹配多个字符来匹配多个字符 正则表达式中,“*”和“+”都可以匹配多个该符号之前的字符。但是,“+”至少表示一个字符,而“*”可以表示0个字符。【例例5-37】下面从info表name字段中查询字母c之间出现过a的记录。SQL代码如下:SELECT*FROM info WHERE name REGEXP a*c;代码执行结果如下:图5-53 使用“*”来匹配多个字符 查询结果显示,Aric、Eric和Lucy中的字母c之前并没有a。因为你“*”可以表示0个,所以“a*c”表示字母c之前有0个或者多个a出现。上述的情况都是属于前面出现过0个的情况。如果使用+,其SQL代码如下:SELECT*
50、FROM info WHERE name REGEXP a+c;代码执行结果如下:图5-54 使用“+”来匹配多个字符查询结果只有一条。只有Jack是刚好字母c前面出现了a。因为a+c表示字母c前面至少有一个字母a。5.9 5.9 综合实例综合实例使用正则表达式查使用正则表达式查询学生成绩信息询学生成绩信息 本实例将在学生成绩信息表computer_stu中查找姓名(name)字段中以L开头,以y结束的,中间包含两个字符的学生的成绩信息,运行结果如图5-55所示。图5-55 使用正则表达式查询学生成绩信息 要实现查询姓名(name)字段中以L开头,以y结束的,中间包含两个字符的学生成绩,可以通