授课日期
        6
授课形式
讲课
授课时数
4
章节名称
08 简单查询
教学目的与要求
①掌握使用Join…On…子句进行多表自然连接查询
②掌握左外连接、右外连接和完全外连接
③掌握自连接查询
④掌握子查询的分类(单行子查询、多行子查询)
⑤掌握在Where子句中使用子查询作为查询条件
⑥掌握在From子句中使用子查询作为数据源
⑦掌握使用子查询在Insert Into语句中为数据表插入另一表中的已有数据。
⑧掌握使用子查询在update语句中进行基于外表条件的数据修改。
⑨掌握使用子查询在delete from语句中进行基于外表条件的数据删除。
教学重点
连接查询、自查询
教学难点
自连接查询
教学方法和手段
讲授法结合课堂实例分析讨论
教学过程与组织
导入新课
我们已经学习了简单的数据查询。前面所讲的数据查询,数据的来源都在一张表中。更多的情况下,需要查询的数据往往分布在多张表,这就需要进行关系代数的连接运算,在连接的结果上进行查询。
讲授新课
09 连接查询和子查询
01 多表连接查询
多表查询又称作连接查询,或称作联合查询。连接查询又可分成内连接查询、外连接查询等等。内连接查询中,又可分为等值连接、非等值连接、自连接等子类。外连接中,又可分为左外连接、右外连接等。
9.1.1 内连接(自然连接)
两个表的内连接查询是指,从两个表中的相关字段中提取信息作为查询的条件,如果满足查询的条件,就从两个表中的相关记录中,选择需要的信息,连接成一个元组,置于查询结果集之中,这就是内连接的主要作用。内连接语句的格式和语法如下:
FROM 1 [INNER] JOIN 2 ON 连接条件表达式
连接查询的语句,主要是在单表查询的语句中,对数据源部分进行了语法成份的扩展。用以申明是哪两个表联合查询。ON之后的条件表达式,说明了连接的条件。连接条件表达式的格式有特殊要求。其一般格式为:
[表名1.]列名1 比较运算符 [表名2.]列名2
如果某个列所表示的数据在查询语句涉及到的多张表中存在,且列名相同,使用时就应该在其前面冠上表名,并以圆点(.)隔开。当确认某个列名只出现在一张表时,它前面的表名才可以省略。
连接查询语句中,SELECT之后的列名列表也应这样表示:
SELECT [表名.]列名1, , [ 表名.]列名n FROM
连接条件中,两个表中的比较列,必须是语义相同的列,才可以构成有意义比较条件。
例:查询每个学生的情况和选课情况
Select * From Student Inner Join SC On Student.SNo = SC.SNo
例:在上例中,只选取学号、姓名、课程号和成绩
Select SC.SNo, Student.SName, SC.CNo, SC.Grade From Student Inner Join SC On Student.SNo = SC.SNo
例:查询系编号为g001g005各学生的选课情况和每门课的成绩,将每个系的名单排在一起
Select Student.SName, SC.CNo, SC.Grade From Student Inner Join SC On Student.SNo=SC.SNo Where Student.Depart='g001' Or Student.Depart = 'g005' Order By Student.Depart;
例:在上例中,使用表的别名
Select S.SName, SC.CNo, SC.Grade From Student S Inner Join SC On S.SNo=SC.SNo Where S.Depart = 'g001' Or S.Depart = 'g005' Order By S.Depart;
例:查询计算机系中选修了课程名为VB的课程的学生姓名和成绩
Select S.SName, C.CName, SC.Grade From Student S Join SC On S.SNo=SC.SNo Join Course C On C.CNo =SC.CNo Where S.Depart='g001' And C.CName='VB'
例:查询所有选修了VB课程的学生姓名和所在系编号
Select S.SName, S.Depart From Student S Join SC On S.SNo=SC.SNo Join Course C On C.CNo=SC.CNo Where C.CName='VB'
9.1.2 自连接
连接操作不仅可以在不同的表上进行,而且在同一张表内可以进行自身连接,即将同一个表的不同行连接起来。自连接可以看作一张表的两个副本之间的连接。在自连接中,必须为表指定两个别名,使之在逻辑上成为两张表。
自连接的处理思想是,将物理上的一个表,从逻辑上视同两个表。使用自连接必须为同一张表取两个别名,让一个表变成表名不同的两个表,仅此而已。其余的工作与两表连接查询无任何区别。
例:查询与冯巩在同一个系学习的学生的姓名和系编号
Select S2.SName, S2.Depart From Student S1 Join Student S2 On S1.Depart=S2.Depart Where S1.SName='冯巩' And S2.SName<>'冯巩'
9.1.3 外连接
外连接的思想是,当一个表中的元组,如果在另一表中不到与其连接条件相匹配的元组时,并不将此元组的数据抛弃,而是将该元组的相关信息(结果中需要的列值)与连接的另一个表的空值列(全部取空值),也在形式上连接成新的元组,并将它置于查询结果中。这样一来,就达到了用户想保留某些信息的目的。
外连接是左外连接和右外连接的统称。语句结构和语法规则如下:
FROM 1 LEFT | RIGHT [OUTER] JOIN 2 ON 连接条件
LEFT [OUTER] JOIN 称作左外连接,RIGHT [OUTER] JOIN称作右外连接。
左外连接将在查询结果中,除了输出满足自然连接条件的结果外,还输出表1里面那些在表2不到对应匹配的数据行的相关信息。
右外连接将在查询结果中,除了输出满足自然连接条件的结果外,还输出表2里面那些在表1不到对应匹配的数据行的相关信息。
例:查询每个学生的学号、姓名、所选课程、成绩,即使有学生没有选课,也要列出他的信息
Select S.No, S.SName, SC.CNo, SC.Grade From Student S Left Join SC On S.SNo=SC.SNo
例:将例5-42的左外连接改成右外连接,观察查询结果有什么不同
Select S.No, S.SName, SC.CNo, SC.Grade From Student S Right Join SC On S.SNo=SC.SNo
9.1.4 交叉连接
交叉连接也叫非限制连接,它将两个表不加任何约束地组合起来。在数学上,就是两个表的笛卡尔积。交叉连接后得到的结果集的行数是两个被连接表的行数的乘积。
语法如下:
SELECT 字段列表 FROM 表1 CROSS JOIN 表2
SELECT 字段列表FROM 表1 ,表2
例:列出所有学生的有可能的选课组合
SELECT S.SNO, S.SNAME, C.CNO, C.CNAME FROM STUDENT S CROSS JOIN COURSE C
在实际应用中使用交叉连接产生的结果集一般没有什么意义,但在数据库的数学模式上有重要的作用。
02 子查询
8.2.1子查询的概念和分类
在SQL语言中,将一个SELECT FROM WHERE语句称作一个查询块。如果将一个SELECT语句嵌套在下列语句之中,则称这样一类语句为子查询语句或内层查询语句,而位于外面(包含子查询语句)的语句则称为主查询语句或外层查询语句。可以作为主查询的语句的有以下几个:
(1)SELECT语句;
(2)INSERT语句;
(3)UPDATE语句;
(4)DELETE语句。
sql中union多表合并子查询可以嵌套。
子查询往往作为在某一查询的Where条件句或Having子句的一部分,或者作为查询的某个数据源。子查询分为两种:单行子查询(子查询的返回结果只有一行)和多行子查询(字查询的结果在两行或者两行以上)。
8.2.2 使用子查询的结果作比较
当确认一个子查询语句的查询结果是一个单一值时,这样的子查询语句可以置于任何带比较运算符的条件表达式的一端,构成一个条件表达式。比较运算符可以是=、<、>、<=、>=、<>、!=等中的一个。
例: 查询选修了C02号课程且成绩比此课程的平均分高的学生的学号、成绩
Select SNo, Grade From SC Where CNo='C02' And Grade > (Select Avg(Grade) from SC Where CNo='C02')
该语句的执行过程如下(1)先执行括号内的子查询;(2)将子查询的结果代入外层查询中;(3)执行外层查询语句。
需要注意的是,当子查询的结果作为外层查询语句的条件的一部分,且外层查询语句的条件使用到了“=、<、>、<=、>=、<>、!=”这样的运算符,必须使用单行子查询。
8.2.3 使用子查询的结果作集合
当确认一个子查询语句的结果集中的值的行数大于一(多行子查询)的情况下,它不能与比较运算符一起使用,而只能使用集合运算符IN或NOT IN,将一个表达式的值与查询返回的结果集进行比较。如果表达式的值在子查询的结果集合中,条件为真,反之,条件为假。
注意,子查询语句中只能返回一组类型相同的值,且要求其返回值的数据类型与测试表达式的数据类型一致。
例:查询与冯巩在同一个系学习的学生的学号、姓名和系编号
Select SNo, SName, Depart From Student Where Depart In (Select Depart From Student Where SName='冯巩')
例:查询C06号课程的成绩90分以上的学号和姓名
Select SNo, SName From Student Where SNo In (Select SNo From SC Where Grade>=90 And CNo='C06')
或者
Select S.SNo, S.SName From Student S Join SC On S.SNo=SC.SNo Where SC.Grade>90 And SC.CNo='C06'
例:查询选修了'数据库基础'课程的学生学号和姓名
Select S.SNo, S.SName From Student S Join SC On S.SNo=SC.SNo Join Course C On C.CNo=SC.CNo Where CName='数据库基础'
或者
Select Sno, SName From Student Where SNo In (Select SNo From SC Where CNo=(Select CNo From Course Where CName='数据库基础'))
8.2.3 使用子查询进行逻辑测试
使用子查询进行逻辑测试,是使用存在性谓词EXISTS。在这个谓词后面带一个子查询语句,这一语句执行后并不返回具体数据,而只返回一个逻辑值,或者返回“真”,或者返回“假”。
例:查询选修了课程C20的学生姓名。
Select SName From Student Where Exist (Select * From SC Where SNo=Student.SNo And CNo='C20')
该语句的处理过程如下:
1)到外层Student表的第1行,根据其SNo值处理内层查询;
2)用外层的值执行内层查询,如果有符合条件的数据,则Exist返回True,否则返回False。如果Exist返回True,则外层结果中的当前数据为符合条件的结果;否则,是不符合条件的结果;
3)顺序处理外层Student表的第2行、第3行……直到处理完所有的行。
如果在Exist前加上Not,则表示,当子查询语句中不存在任何满足条件的记录时,返回Ture,当子查询语句存在满足条件的记录时,返回False
例:查询没有选修C01课程的学生姓名和所在系编号
Select SName, Depart From Student S Where Not Exist (Select * From SC Where SC.SNo=S.SNo And CNo='C01')
03 多个相同模式的查询结果的并、交、差
我们在关系代数中提到了两个相同关系模式的关系,能够进行交、并、差运算。在T-SQL中,相同关系模式的关系之间的交、并、差运算,分别是通过INTERSECT、UNION、EXCEPT运算符实现的。
8.3.1 Union运算符
使用UNION语句可以把两个或两个以上的查询产生的结果集合并为一个结果集。语法格式如下:
SELECT语句
UNION  [ALL]
SELECT语句
说明:
(1)UNION中的每一个查询所涉及的列必须具有相同的列数、相同的数据类型,并以相同的顺序出现。
(2)最后结果集中的列名来自第一个SELECT语句。
(3)若UNION中包含ORDER BY子句,则将对最后的结果集排序。
(4)在合并结果集时,默认从最后的结果集中删除重复的行,除非使用ALL关键字。
例:在同一列中显示所有的学生的学号和课程号、课程名
SELECT SNo, SName FROM Student
UNION
SELECT CNo, CName FROM Course
8.3.2 Intersect运算符
INTERSECT运算符返回INTERSECT左右两边的两个查询结果集的交集。语法格式如下:
SELECT语句
INTERSECT
SELECT语句
说明:
(1)INTERSECT中的每一个查询所涉及的列必须具有相同的列数、相同的数据类型,并以相同的顺序出现。
(2)最后结果集中的列名来自第一个SELECT语句。
(3)若INTERSECT中包含ORDER BY子句,则将对最后的结果集排序。
8.3.3 Except运算符
EXCEPT运算符返回EXCEPT左右两边的两个查询结果集的差集,即第一个结果集与第二个结果集的差集。语法格式如下:
SELECT语句
EXCEPT
SELECT语句
说明:
(1)EXCEPT中的每一个查询所涉及的列必须具有相同的列数、相同的数据类型,并以相同的顺序出现。
(2)最后结果集中的列名来自第一个EXCEPT语句。
(3)若EXCEPT中包含ORDER BY子句,则将对最后的结果集排序。
例:查询没有选课的学生的学号
SELECT SNo From Student
EXCEPT
SELECT SNo From SC
04 基于外表条件的数据更新
以前学习的对表的插入、修改和删除,都是基于本表条件的。事实上存在更复杂的情况:基于外表条件的数据修改和删除。
8.4.1 基于外表条件的数据修改
例: 将选修了'计算机原理'课程,且成绩低于60分的人,每人加5分
Update SC Set Grade=Grade+5 Where Grade<60 And SNo In (Select SNo From SC Join Course C On SC.CNo=C.CNo Where CName='计算机原理')
例: 取消'高等数学'课程全部已录入成绩,但保留选课记录
Update SC Set Grade=NULL Where SNo In (Select SNo From SC Join Course C On SC.CNo=C.CNo Where CName='高等数学')
8.4.2 基于外表条件的数据删除
例:删除SC表中,'动画设计'课程低于50分的选课记录
Delete From SC Where Grade<50 And CNo In (Select CNo From SC Join Course C On SC.CNo = C.CNo Where CName = '动画设计')
8.4.3 将查询结果插入新表
使用SELECT INTO语句可以在查询的基础上创建新表,SELECT INTO语句首先创建一个新表,然后用查询的结果填充新表。
语法格式为:
SELECT  目标列集合 INTO 新表 FROM 源表
[WHERE 条件1]
[GROUP BY 表达式1 [HAVING 条件2]]
[ORDER BY 表达式2[ASC|DESC]]
例:创建一个新表SC001,包含该表不设置约束,包含学号、姓名、课程号、课程名、成绩5列,并将系编号为g001的系的全体学生所修的课程信息插入新表SC001
SELECT S.SNo SNo, S.SName, C.CNo, C.CName, SC.Grade INTO SC001 FROM Student S JOIN SC ON S.SNo=SC.SNo JOIN COURSE C ON SC.CNo=C.CNo WHERE S.Dept= 'g001'
作业
1、 查询每个系的系编号、教师总人数、平均薪水。
2、 查询编号为“05”的系中,比平均薪水低的教师的教工编号、姓名、薪水。
3、 查询职称为“助教”和“讲师”的教工的教工编号、姓名、性别、年龄、系主任姓名、所在系电话,要求使用自然连接。
4、 查询每个系的系编号、系名称、电话、主任教工号、主任姓名,如果某个系暂时没有主任,也要将这样的系显示出来。
5、 查询同姓同名的老师,显示他们的教工编号、姓名、性别、所在系编号,要求使用自连接。
6、 查询“文雄军”老师所在的系的编号、系名称,要求使用子查询。
7、 查询比院系编号为“06”的院系的教工数量更多的院系的编号、名称、教工数量、教工平均薪水,要求使用子查询。
8、 创建一张新表TeacherComputer,表的结构和Teacher表的结构完全一样,同时插入“计算机系”的所有教师信息,要求使用子查询
9、 查询职称为“助教”的教工的教工编号、姓名、性别、年龄、系主任姓名,并按照薪水从低到高排序。
教学内容的深化和拓展
课堂小结
教学后记

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。