4.8.3 SQL数据查询
Select语句是SQL的核心,其主要功能是实现数据源数据的筛选、投影和连接操作,并完成筛选字段的重命名、分类汇总、排序等操作、具有强大的数据查询功能。
Select语句的语名包括多个子句,结构如下:
Select[谓词]<字段列表>∣<目标表达式>∣<函数>[As别名]
From表名或查询名列表
[Where条件…]
[Group By字段名]
[Having分组的条件]
[Order By字段名[Asc|Desc]];
该语句的功能:从指定的表或查询中按设置的条件,查找满足条件的记录。
Select语句各个部分的含义如下。
(1)谓词:常使用的是ALL、Distinct和Top,可用谓词限制返回的记录数量。如果没有指定谓词,则默认值为ALL。Top n列出最前面的n条记录。Distinct去掉查询结果中指定字段的重复值,显示不重复的值。
(2)字段列表:多个字段时,各字段之间用“,”分隔。可以使用“*”代表源数据表中全部字段;可以在查询字段名前指明字段的来源数据表,如“学号表.学号”表明“学号”来源于“学生表”。
(3)目标表达式或函数:查询计算的表达式或函数。
(4)别名:列标题,以代替表中原有的列名。
(5)From:获取数据的源数据表。如果是多个表,表名之间用“,”分隔。
(6)Where:查询的条件。Where是可选的,省略表示选择全部记录,使用时必须接在From之后。
(7)Group By:查询结果按指定的列进行分组。
(8)Having:指定分组的条件,Having子句是可选的,使用时必须放在Group By子句后面。
(9)Order By:按指定字段对查询的结果排序。其中,Asc代表递增,Desc代表递增,默认为递减。
1.单表查询
单表查询是指查询的数据源来源于一个数据表或者一个查询。
任务4.21 编写SQL查询语句,查询“学生表”的所有字段,保存为“SQL学生查询”。
操作步骤:
(1)单击“创建”选项卡→“查询”组→“查询设计”,打开“查询1”的设计视图,关闭“显示表”对话框。
(2)单击“查询工具/设计”上下文选项卡→“结果”组→“视图”向下按钮,在列表框中选择“SQL视图”选项,进入“查询1”的“SQL视图”,输入如下SQL语句,保存,运行。
SELECE*
FROM学生表;
说明:星号“*”表示“学生表”的所有字段。
任务4.22 编写SQL查询语句,查询“教师表”中所有职称。保存为“SQL消除重复值查询”
操作步骤:
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECE DISTINCT职称
FROM教师表;
说明:
(1)根据数据表的约束规则,表中记录不允许重复,但查询输出的是数据源的部分字段时,查询结果就有可能存在重复记录,使用Distinct消除重复记录。Distinct消除的是记录的重复值,而不是某个字段的重复值。如果查询中只定义了一个字段,字段值也就是记录值。
(2)Distinct必须紧挨着Select,放在Select后面的目标字段的前面。
任务4.23 编写SQL查询语句,查询“教师表”中入院时间超过10年的教师信息,包括“教师编号”、“姓名”、“性别”、“出生日期”、“入院日期”(降序)及“职称”,保存为“SQL工龄查询”。
提示:“入院时间超过10年”计算方法是合成10年前的日期,表达式为:DateSerial(Year(Date())-10,Month(Date()),Day(Date())),(其中DateSerial(year,month,day),由year、month、day三个数值构成日期),如果入院时间小于此日期,表示入院时间超过10年。
操作步骤:
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT教师编号,姓名,性别,职称,入院日期,职称
FROM教师表
WHERE入院日期<=DateSerial(Year(Date())-10,Month(Date()),Day(Date()))
ORDER BY入院日期Desc;
2.多表查询
在查询应用中,常常需要组合两个或两个以上表中数据,以输出完整的信息。例如输出“学号”、“姓名”、“课程名称”及“成绩”,数据源为“学生表”、“课程表”和“成绩表”三表。
连接数据表的方法有两种,一种是用Where子句,另一种是通过INNER JOIN子句。
任务4.24 编写SQL查询语句,查询学生的课程信息,显示“学号”、“姓名”、“课程名称”、“成绩”,数据源为“学生表”,“课程表”和“成绩表”,分别用Where子句和INNER JOIN子句实现连接,分别保存为“SQL学生成绩查询1”和“SQL学生成绩查询2”。
操作步骤(用WHERE实现连接):
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT学生表.学号,学生表.姓名,课程表.课程名称,成绩表.成绩
FROM学生表,课程表,成绩表
WHERE学生表.学号=成绩表.学号AND课程表.课程编号=成绩表.课程编号;
操作步骤(用INNER JOIN实现连接):
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT学生表.学号,学生表.姓名,课程表.课程名称,成绩表.成绩
FROM学生表INNER JOIN(课程表INNER JOIN成绩表ON课程表.课程编号=成绩表.课程编号)ON学生表.学号=成绩表.学号;
说明:
(1)用WHERE不仅可设置查询条件,还可设置表间的关联。
(2)查询字段引用多表中的同名字段时,必须指明来源哪个数据表,方法是:表名.字段名。
(3)通过INNER JOIN子句连接的格式为:
SELECT<字段名表>
FORM<表1>[INNER JOIN<表2>ON<连接条件>]
(4)INNER JOIN可嵌套连接,连接时先内层后外层。
任务4.25 编写SQL查询语句,查询“10市场营销1班”学生,显示“学号”、“姓名”、“性别”和“班级名称”。保存为“SQL班级查询”。
操作步骤(用INNER JOIN实现连接):
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT学生表.学号,学生表.姓名,学生表.性别,班级表.班级名称
FROM班级表INNER JOIN学生表ON 班级表.班级编号=学生表.班级编号
WHERE班级表.班级名称="10市场营销1班";
任务4.26 编写SQL查询语句,查询没参加“数据库技术与应用”考试的学生“学号”、“姓名”、“班级名称”。分别用Where子句和INNER JOIN子句实现连接,分别保存为“SQL没成绩查询1”和“SQL没成绩查询2”。
操作步骤(用WHERE实现连接):
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT学生表.学号,学生表.姓名,班级表.班级名称
FROM学生表,班级表,课程表,成绩表
WHERE(班级表.班级编号=学生表.班级编号AND学生表.学号=成绩表.学号AND课程表.课程编号=成绩表.课程编号)AND课程表.课程名称="数据库技术与应用"AND成绩表.成绩IS NULL
操作步骤(用INNER JOIN实现连接):
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT学生表.学号,学生表.姓名,班级表.班级名称
FROM班级表INNER JOIN(学生表INNER JOIN(课程表INNER JOIN成绩表ON课程表.课程编号=成绩表.课程编号)ON学生表.学号=成绩表.学号)ON班级表.班级编号=学生表.班级编号
WHERE课程表.课程名称="数据库技术与应用"AND成绩表.成绩IS NULL
说明:成绩表.成绩IS NULL 表是成绩列中没有数据,即没有考试。
3.计算查询
计算查询实质是设计一个表达式,作为一个整体,等同于一个字段,并用“标题”表示,其格式为:
计算表达式AS计算表达式标题
任务4.27 编写SQL查询语句,查询学生的“学号”、“姓名”、“出生日期”并计算“年龄”(升序),保存为“SQL年龄查询”。
操作步骤:
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT学号,姓名,出生日期,YEAR(DATE())-YEAR(出生日期)AS年龄
FROM学生表
ORDER BY YEAR(DATE())-YEAR(出生日期)ASC;
说明:
“YEAR(DATE())-YEAR(出生日期)”为计算表达式,“年龄”为计算表达式的“标题”,“标题”不能代表计算表达式的本身,不能用作引用,排序时,只能使用计算表达式本身,而不是用“年龄”。
任务4.28 编写SQL查询语句,查询平均分大于85分的学生,查询字段为“学号”、“姓名”、“班级名称”、“平均分”(保留1位小数,降序),保存为“SQL平均分查询”
操作步骤:
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT学生表.学号,学生表.姓名,班级表.班级名称,ROUND(AVG(成绩表.成绩),1)AS平均分
FROM学生表,班级表,课程表,成绩表
WHERE班级表.班级编号=学生表.班级编号AND学生表.学号=成绩表.学号AND课程表.课程编号=成绩表.课程编号
GROUP BY学生表.学号,学生表.姓名,班级表.班级名称
HAVING ROUND(AVG(成绩表.成绩),1)>=85
ORDER BY ROUND(AVG(成绩表.成绩),1)DESC
说明:
(1)GROUP BY表示分组,由于在查询结果中显示有学生.学号,学生.姓名,班级.班级名称,所以必须以这3个字段作为分组的依据。即在查询显示字段必须是分组的字段,否则有错。
(2)HAVING表示分组统计后的条件。
任务4.29 编写SQL查询语句,查询各系学生的人数。保存为“SQL人数查询”。
操作步骤:
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT班级表.所属系,Count(学生.学号)AS学生人数
FROM班级表INNER JOIN 学生表ON班级表.班级编号=学生表.班级编号
GROUP BY班级表.所属系
4.参数查询
参数查询的参数设置在WHERE中,其参数名用“[]”括起来,运行查询时,弹出“参数输入”框,输入参数,根据参数计算条件表达式。
任务4.30 编写SQL查询语句,建立“输入姓氏”参数,查询学生的“学号”,“姓名”,“性别”和“出生日期”。保存为“SQL参数查询”。
操作步骤:
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT学号,姓名,性别,出生日期
FROM学生表
WHERE LEFT(姓名,1)LIKE[输入姓氏];
5.嵌套查询
在SQL语言中,当一个查询是另一个查询的条件时,即在一个SELECT语句的WHERE子句中出现另一个个SELECT语句,这种查询称为嵌套查询。通常把内层的查询子句称为“子查询”,调用“子查询”的查询语句称为“父查询”。
嵌套查询一般设计为只有一个字段的查询,如果查询结果只有一条记录,即字段单值,使用条件表达式为:字段名关系运算符(子查询),如果查询结果有多条记录,即查询字段多值,使用条件表达式为:字段名IN(子查询)。
任务4.31 编写SQL查询语句,查询工资高于工资平均值的“教师编号”、“姓名”、“职称”和“工资”。保存为“SQL高工资查询”
操作步骤:
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT教师编号,姓名,职称,工资
FROM教师表
WHERE工资>=(SELECT AVG(工资)FROM教师表)
说明:
(1)如果条件编写为“WHERE工资>=AVG(工资)”,查询无法运行,提示条件子句中不能含有合计函数的错误,这是因为没有为合计函数AVG(工资)提供数据来源。
(2)“SELECT AVG(工资)FROM教师表”子查询先执行,结果暂存在计算机内存中,执行父查询时,此值带入条件表达式进行计算。
(3)子查询是一个完整的查询,一定要有数据源,必要时还可设置条件,分组等,但不能设置排序。
任务4.32 编写SQL查询语句,查询选修“管理学”或“经济学”的学生“学号”。保存为“SQL选修课程查询”
操作步骤:
进入“查询1”SQL视图,输入如下SQL语句,保存、运行。
SELECT学号
FROM 成绩表
WHERE课程编号in(SELECT课程编号FROM课程表WHERE课程名称="管理学"OR课程名称="经济学")