8.4 数据查询语言
数据查询语言用于从一个或者多个表中,查询用户所需要的数据,相对应的SQL语句是SELECT…FROM…WHERE和UNION等。
创建方法:同前述的“数据操作语言”。对于“联合”查询,可以在查询的“设计视图”下,单击“查询工具”的“设计”上下文选项卡,单击“查询类型”组中“联合”按钮;在“SQL视图”中输入相应的“Access SQL语句”,单击“结果”组中的“运行”按钮。
8.4.1 数据查询语法
查询数据通常使用SELECT…FROM…WHERE,用法如下:
SELECT[ALL|DISTINCT][*]<目标列表达式>[,<目标列表达式>]…
FROM<表名>[,<表名>,…]…
[WHERE<条件表达式>]
[GROUP BY<字段>[HAVING<条件表达式>]]
[ORDER BY<字段>[ASC|DESC]]
SELECT:显示指定字段;All:所有记录;*:所有字段;DISTINCT:去掉重复记录。
FROM:查询对象(表)。
WHERE:查询条件;省略WHERE,查询所有元组。
GROUP BY:对查询结果按指定字段分组,字段值相等的记录分为一组。通常会在每组中使用集函数,实现分类统计。HAVING:筛选出满足指定条件的分组。
ORDER BY:对查询结果按照指定字段升序/降序排序(ASC/DESC),默认升序。
SELECT语句的功能是根据WHERE指定的条件,按照SELECT指定的目标列表达式,从FROM指定的表中,查询出相应的数据集合。
8.4.2 数据查询范例
SELECT语句作为SQL的核心,提供了丰富的功能选项,从而可以非常方便地实现选择、投影和连接及其复杂的嵌套和统计查询等。
查询默认使用学籍数据库中的专业、学生、课程和选课4张表。
8.4.2.1 选择查询
选择查询的基本格式:
SELECT*
FROM<表>
WHERE<表达式>
<表达式>:使用关系运算符(+,-,*,/,<,<=,>=,>,!=,<>,=)和逻辑运算符(NOT,AND和OR等),把常量、字段和函数,按照指定的语法规则连接起来的有意义的组合。
【例8.9】查询学生表中,所有男生信息。SQL语句如下:
SELECT*FROM学生WHERE性别='男'
【例8.10】查询年龄大于18而且小于22岁的学生。SQL语句如下:
SELECT*
FROM学生
WHERE(YEAR(DATE())-YEAR([生日]))>18 AND(YEAR(DATE())-YEAR([生日]))<22
▲思考:查询学生表中,通过四级的学生信息。
▲提示:SELECT*FROM学生WHERE是否四级=True。
8.4.2.2 投影查询
投影查询的基本格式:
SELECT<目标列表达式>[AS名称][,<目标列表达式> [AS名称]]…
FROM<表>
<目标列表达式>:可以是字段,或者<表达式>。
【例8.11】查询学生的姓名和年龄。SQL语句如下:
SELECT姓名,YEAR(DATE())-YEAR([生日])AS年龄
FROM学生
【例8.12】查询通过四级的男生的姓名和年龄。SQL语句如下:
SELECT姓名,YEAR(DATE())-YEAR([生日])AS年龄
FROM学生
WHERE是否四级=True AND性别='男'
▲提示:如果<目标列表达式>不是表中的字段,则可以使用AS为其重新命名。
8.4.2.3 BETWEEN查询
BETWEEN查询的基本格式:
<字段>BETWEEN<表达式1>AND<表达式2>
BETWEEN表示大于等于<表达式1>,而且小于等于<表达式2>的查询。
【例8.13】查询高考成绩在600到620之间(包含600和620)的学生的姓名和年龄。SQL语句如下:
SELECT姓名,YEAR(DATE())-YEAR([生日])AS年龄
FROM学生
WHERE高考成绩BETWEEN600 AND620
8.4.2.4 枚举查询
枚举查询可以使用关键字IN。基本格式:
<字段>IN(<表达式1>,<表达式2>,…,<表达式n>)
【例8.14】查询专业号不是010102和030101的学生的学号和姓名。SQL语句如下:
SELECT学号,姓名
FROM学生
WHERE专业号NOT IN('010102','030101')
8.4.2.5 模糊查询
模糊查询可以使用关键字LIKE。基本格式:
<字段>LIKE<文本表达式>
<文本表达式>:可以使用通配符“*”和“?”。“*”表示任意多个任意符号,包括长度是0的空串。“?”表示任意的单个字符。
例如:x*y表示以x开头,以y结尾的任意长度的字符串。x?y表示以x开头,以y结尾的长度为3的任意字符串。
【例8.15】查询所有姓李的学生的学号、姓名和高考成绩。SQL语句如下:
SELECT学号,姓名,高考成绩
FROM学生
WHERE姓名LIKE'李*'
【例8.16】查询学号以“110”开头,且倒数第1和第3个字符分别为2和4的学生信息。SQL语句如下:
SELECT*
FROM学生
WHERE学号LIKE'110*4?2'
8.4.2.6 分类统计
分类统计可以使用关键字GROUP BY,并且配合COUNT、SUM、AVG、MAX和MIN等来实现。基本格式:
GROUP BY<字段>[HAVING<条件表达式>]
【例8.17】查询学生的男女生人数。SQL语句如下:
SELECT性别,COUNT(*)AS人数
FROM学生
GROUP BY性别
【例8.18】查询男女生高考成绩的最高分、最低分和平均分。SQL语句如下:
SELECT性别,MAX(高考成绩)AS最高分,MIN(高考成绩)AS最低分,
AVG(高考成绩)AS平均分
FROM学生
GROUP BY性别
▲思考:在课程表,统计所有课程的最高学时和学分,最低学时和学分,平均学时和学分,学时的总合,学分的总和和课程门数。
【例8.19】查询至少选修了4门课程的学生的学号。SQL语句如下:
SELECT学号
FROM选课
GROUP BY学号HAVING COUNT(*)>=4
【例8.20】查询2门以上期末成绩大于等于85分的学生的学号。SQL语句如下:
SELECT学号
FROM选课
WHERE期末>=85
GROUP BY学号HAVING COUNT(*)>=2
▲提示:如果SELECT语句中使用了GROUP BY,则统计函数对每个分组有效(即分类统计)。先对满足条件的元组进行分组,然后统计每一个分组的相应数据。COUNT()相当于分类统计元组的个数;AVG()相当于分类求平均值;SUM()相当于分类求和;MAX()相当于分类求最大值;MIN()相当于分类求最小值。
8.4.2.7 排序查询
对查询结果进行排序,可以使用关键字ORDER BY。基本格式:
ORDER BY<字段>[ASC|DESC][TOP<表达式>[PERCENT]]
TOP<表达式>:仅显示前若干记录;PERCENT:按照百分比显示前若干记录。
【例8.21】查询学生的学号、姓名和高考成绩,并且按高考成绩降序排序,仅显示前百分之二十。SQL语句如下:
SELECT TOP20 PERCENT学号,姓名,高考成绩
FROM学生
ORDER BY高考成绩DESC
▲思考:在例8.21中,如何显示前10名。
8.4.2.8 连接查询
连接查询是数据查询的灵魂。用户可以通过连接查询,非常方便灵活地从多个表中,获取自己所需要的信息。使用方法如下:
SELECT<字段列表>
FROM<表1>[INNER JOIN<表2>ON<连接条件>,…]
或者
SELECT<字段列表>
FROM<表1>,<表2>
WHERE<选择条件>AND<连接条件>
<连接条件>:通常使用自然连接,即按照两个表的公共字段相等的方式进行连接。如果公共字段是A,则连接格式为“<表1>.A=<表2>.A”。
【例8.22】查询学生的姓名、课程名和期末成绩。SQL语句如下:
SELECT姓名,课程名,期末
FROM学生,课程,选课
WHERE学生.学号=选课.学号AND课程.课程号=选课.课程号
或者
SELECT姓名,课程名,期末
FROM学生INNER JOIN(课程INNER JOIN选课ON课程.课程号=选课.课程号)
ON学生.学号=选课.学号
▲提示:在实际中,进行多表连接时,通常有意义的连接是自然连接,这时一定要注意,不要把默认的自然连接条件忘掉。默认连接条件就是表之间的公共属性相等。如果省略连接条件,则执行结果是多表的笛卡儿积,这在实际中,会产生大量没有意义的数据。
▲思考:执行并分析如下SQL查询:
SELECT姓名,课程名,期末
FROM学生,课程,选课
【例8.23】查询选修英语且期末成绩大于85分的学生学号和姓名。SQL语句如下:
SELECT学生.学号,姓名
FROM学生,课程,选课
WHERE课程名='英语'AND期末>85 AND
学生.学号=选课.学号AND课程.课程号=选课.课程号
【例8.24】查询每门课程的课程号和课程名,期末成绩的最高分、最低分和平均分。SQL语句如下:
SELECT选课.课程号,课程名,COUNT(选课.课程号)AS人数,
MAX(期末)AS最高,MIN(期末)AS最低,ROUND(AVG(期末),1)AS平均
FROM课程,选课
WHERE课程.课程号=选课.课程号
GROUP BY选课.课程号,课程名
【例8.25】查询每个学生的学号、姓名、课程名和成绩,其中总分是平时、期中和期末按照10%、30%和60%计算。SQL语句如下:
SELECT学生.学号,姓名,课程名,平时*0.1+期中*0.3+期末*0.6 AS总分
FROM学生,课程,选课
WHERE学生.学号=选课.学号AND课程.课程号=选课.课程号
8.4.2.9 嵌套查询
查询语句作为一个整体,可以将其嵌套在另一个查询语句的WHERE子句的条件中,从而构成嵌套查询。在实际应用,对于某些特殊查询,嵌套查询会带来一定的方便,但是对有一些查询则不然,因此,需要根据实际情况来选择使用嵌套。IN之后的选择结果只有一个值时,可以使用等号“=”代替。
【例8.26】查询与“刘夏”同专业的学生的学号、姓名和专业号。SQL语句如下:
SELECT学号,姓名,专业号
【例8.27】查询选修了课程名为“高等数学”的学生学号和姓名。SQL语句如下:
SELECT学号,姓名
8.4.2.10 ANY/ALL查询
ANY/ALL通常用于与任意一个值比较,或者与所有的值比较的情况。ANY表示任意一个值;ALL表示所有值。常用格式:
>ANY:大于子查询结果中的某个值。
>ALL:大于子查询结果中的所有值。
<ANY:小于子查询结果中的某个值。
<ALL:小于子查询结果中的所有值。
>=ANY:大于等于子查询结果中的某个值。
>=ALL:大于等于子查询结果中的所有值。
<=ANY:小于等于子查询结果中的某个值。
<=ALL:小于等于子查询结果中的所有值。
=ANY:等于子查询结果中的某个值。
=ALL:等于子查询结果中的所有值(通常没有实际意义)。<>ANY:不等于子查询结果中的某个值。
<>ALL:不等于子查询结果中的任何一个值。
【例8.28】查询其他专业中,比专业“010102”的某一个学生年龄小(含同龄)的学生学号、姓名和年龄。SQL语句如下:
【例8.29】查询其他专业中,比专业“010102”的所有学生年龄小(含同龄)的学生学号、姓名和年龄。SQL语句如下:
8.4.2.11 EXISTS查询
EXISTS查询通常不返回数据,仅判断其后的子查询是否存在相应的记录。基本格式:
[NOT]EXISTS(<子查询>)
【例8.30】查询没有选修课程号为“0101”的课程的学生的姓名。SQL语句如下:
【例8.31】查询选修了全部课程的学生的学号和姓名(即没有一门课是他不选的)。SQL语句如下:
【例8.32】查询至少选修了学号为11060203的学生选修的全部课程的学生学号、课程号和期末成绩。即不存在这样的课程,学号11060203选修了该课程,而查询的学生没选。SQL语句如下:
8.4.2.12 联合查询
联合查询用于实现关系代数中的并集。联合查询用于合并两个同类的查询,并且去掉重复的记录。基本格式:
<SELECT查询1>
UNION
<SELECT查询2>
SELECT查询1和SELECT查询2的字段列表必须个数相等、类型相同、顺序一致。
【例8.33】对于学生表和教师通信表,查询学生的姓名和教师的姓名。SQL语句如下:
【例8.34】查询“工商”专业的学生的学号和姓名,以及选修“软件工程”的学生的学号和姓名。SQL语句如下:
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。