数据库系统原理第3章 关系数据库标准语言SQL.ppt
,计算机科学系 2017版,林子雨厦门大学,第3章 关系数据库标准语言SQL(2017版),厦门大学计算机科学系本科生课程数据库系统原理,提纲,3.1 SQL概述3.2 学生-课程数据库3.3 数据定义3.4 数据查询3.5 数据更新3.6 视图,3.1 SQL概述,3.1.1 SQL的产生与发展3.1.2 SQL的特点3.1.3 SQL的基本概念,3.1.1 SQL的产生与发展,1974年,由Boyce和Chamberlin提出,并在IBM公司研制的关系数据库管理系统原型System R 上实现1986年10月,美国国家标准局的数据库委员会X3H2批准了SQL作为关系数据库语言的美国标准,并公布了SQL标准文本1987年,国际标准化组织通过这一标准,3.1.2 SQL的特点,SQL的特点1.综合统一2.高度非过程化3.面向集合的操作方式4.以同一种语法结构提供两种使用方法5.语言简洁,易学易用,1、综合统一(操纵三级模式),SQL,视图1,视图2,基表1,基表2,基表3,基表4,存储文件1,存储文件2,外模式,模式,内模式,5、语言简捷,易学易用,表,语言的动词,SQL,功,能,动,词,数,据,定,义,CREATE,DROP,ALTER,数,据,查,询,SELECT,数,据,操,纵,数,据,控,制,GRANT,REVOKE,3.1 SQL,INSERT,UPDATE,DELETE,第3章 关系数据库标准语言SQL,3.1 SQL概述3.2 学生-课程数据库3.3 数据定义3.4 数据查询3.5 数据更新3.6 视图,3.2 学生-课程数据库,学生-课程数据库学生表:Student(Sno,Sname,Ssex,Sage,Sdept)课程表:Course(Cno,Cname,Cpno,Ccredit)学生选课表:SC(Sno,Cno,Grade),3.2 学生-课程数据库,Student,(a),3.2 学生-课程数据库,Course,(b),3.2 学生-课程数据库,SC,(c),提纲,3.1 SQL概述3.2 学生-课程数据库3.3 数据定义3.4 数据查询3.5 数据更新3.6 视图,3.3 数据定义,3.3.1 模式的定义与删除3.3.2 基本表的定义、删除与修改3.3.3 索引的建立与删除,3.3 数据定义,3.3 数据定义,3.3.1 模式的定义与删除3.3.2 基本表的定义、删除与修改3.3.3 索引的建立与删除,3.3.1 模式的定义与删除,一、定义模式 CREATE SCHEMA AUTHORIZATION Ps:1、若没有指定,那么隐含为2、要创建模式,调用该命令的用户必须具有DBA权限,或者获得了DBA授予的CREATE SCHEMA的权限,例题,例1 定义一个学生-课程模式S-TCREATE SCHEMA“S-T”AUTHORIZATION WANG;为用户“WANG”定义了一个模式S-T,3.3.1 模式的定义与删除,二、删除模式 DROP SCHEMA 其中CASCADE和RESTRICT两者必选其一1、CASCADE(级联),表示在删除模式同时把该模式中所有的数据库对象全部一起删除2、RESTRICT(限制),表示若该模式下已定义了下属的数据库对象,则拒绝删除,例题,例4 删除模式ZHANGDROP SCHEMA ZHANG CASCADE,3.3 数据定义,3.3.1 模式的定义与删除3.3.2 基本表的定义、删除与修改3.3.3 索引的建立与删除,3.3.2 基本表的定义、删除与修改,一、定义基本表,:所要定义的基本表的名字:组成该表的各个属性(列):涉及相应属性列的完整性约束条件:涉及一个或多个属性列的完整性约束条件,CREATE TABLE(,);,例题,例1 建立一个“学生”表Student,它由学号Sno、姓名Sname、性别Ssex、年龄Sage、所在系Sdept五个属性组成。其中学号是主键,并且姓名取值也唯一。,CREATE TABLE Student(Sno CHAR(5)primary key,Sname CHAR(8)UNIQUE,Ssex CHAR(2),Sage INT,Sdept CHAR(10);,例题(续),Sno,Sname,Ssex,Sage,Sdept,字符型,字符型,字符型,整数,字符型,长度为,5,长度为,8,长度为,2,长度为,10,不能为空值,定义基本表(续),常用完整性约束主码约束:PRIMARY KEY唯一性约束:UNIQUE非空值约束:NOT NULL参照完整性约束PRIMARY KEY与 UNIQUE的区别?,例题(续),例2 建立一个“学生选课”表SC,它由学号Sno、课程号Cno,修课成绩Grade组成,其中(Sno,Cno)为主码。,CREATE TABLE SC(Sno CHAR(5),Cno CHAR(3),Grade int,Primary key(Sno,Cno);,二、修改基本表,ALTER TABLE ADD 完整性约束 DROP ALTER COLUMN DROP COLUMN;,:要修改的基本表ADD子句:增加新列和新的完整性约束条件DROP子句:删除指定的完整性约束条件ALTER COLUMN子句:用于修改列名和数据类型DROP COLUMN子句:用于删除列,例题,例2 向Student表增加“入学时间”列,其数据类型为日期型。,ALTER TABLE Student ADD Scome DATETIME;不论基本表中原来是否已有数据,新增加的列一律为空值。,例题,例3 将入学日期的数据类型改为字符型。,ALTER TABLE Student ALTER COLUMN Scome char(8);注:修改原有的列定义有可能会破坏已有数据,语句格式(续),删除属性列,例4 将入学日期列删除掉。,ALTER TABLE Student DROP COLUMN Scome,三、删除基本表,DROP TABLE;基本表删除数据、表上的索引 自动都删除,例题,例5 删除SC表DROP TABLE SC;,3.3 数据定义,3.3.1 模式的定义与删除3.3.2 基本表的定义、删除与修改3.3.3 索引的建立与删除,3.3.3 索引的建立与删除,建立索引是加快查询速度的有效手段建立索引DBA或表的属主(即建立表的人)根据需要建立有些DBMS自动建立以下列上的索引 PRIMARY KEY UNIQUE维护索引 DBMS自动完成使用索引 DBMS自动选择是否使用索引以及使用哪些索引,一、建立索引,语句格式CREATE UNIQUE CLUSTER INDEX ON(,);,用指定要建索引的基本表名字索引可以建立在该表的一列或多列上,各列名之间用逗号分隔用指定索引值的排列次序,升序:ASC,降序:DESC。缺省值:ASCUNIQUE表明此索引的每一个索引值只对应唯一的数据记录CLUSTER表示要建立的索引是聚簇索引,建立索引(续),唯一值索引对于已含重复值的属性列不能建UNIQUE索引对某个列建立UNIQUE索引后,插入新记录时DBMS会自动检查新记录在该列上是否取了重复值。这相当于增加了一个UNIQUE约束,建立索引(续),聚簇索引建立聚簇索引后,基表中数据也需要按指定的聚簇属性值的升序或降序存放。也即聚簇索引的索引项顺序与表中记录的物理顺序一致例:CREATE CLUSTER INDEX Stusname ON Student(Sname);在Student表的Sname(姓名)列上建立一个聚簇索引,而且Student表中的记录将按照Sname值的升序存放,建立索引(续),在一个基本表上最多只能建立一个聚簇索引聚簇索引的用途:对于某些类型的查询,可以提高查询效率聚簇索引的适用范围 很少对基表进行增删操作 很少对其中的变长列进行修改操作聚簇索引的不适用情形表记录太少经常插入、删除、修改的表数据分布平均的表字段,建立索引(续),在下列三种情况下,有必要建立簇索引:(1)查询语句中采用该字段作为排序列(2)需要返回局部范围的大量数据(3)表格中某字段内容的重复性比较大例如,student表中dno(系号)一列有大量重复数据,当在dno列上建立了簇索引后,下面的连接查询速度会加快。,建立索引(续),多列索引和多个单列索引,考虑两种不同的建立索引方式:case 1:对c1,c2,c3三列按此顺序添加一个多列索引;case 2:对c1,c2,c3分别建立三个单列索引;问题1:按c1搜索时,哪种索引效率快?答:case2问题2:按C2搜索时,哪种索引效率快?答:case2,并且,case1的索引无效问题3:按C1,C2,C3搜索哪种效率快?答:case1问题4:按C2,C3,C1搜索时哪种效率快?答:case2,因为没有按多列索引的顺序搜索,case1的索引没有使用到。,覆盖查询简单的说就是所有查询列被所使用的索引覆盖的查询,建立索引(续),如何去建立一个多列索引,最重要的一个问题是如何安排列的顺序是至关重要的比如需要对一个表tb里面的两个字段foo,bar建一个索引,那么索引的顺序是(foo,bar)还是(bar,foo)呢假设tb表有1700条记录,foo字段有750个不同的记录,那么foo字段上的cardinality是750。总规则可以说是cardinality越大的字段应该排在索引的第一位就是说索引的位置是(foo,bar),因为cardinality越大那么第一次取出来的记录集就越小,再进行第二次查询的次数就越少了。,建立索引(续),当在同一表格中建立簇索引和非簇索引时,先建立簇索引后建非簇索引比较好。因为如先建非簇索引的话,当建立簇索引时,SQL Server会自动将非簇索引删除,然后重新建立非簇索引。每个表仅可以有一个簇索引,最多可以有249个非簇索引。它们均允许以一个或多个字段作为索引关键字(Index Key),但最多只能有16个字段。,SQL Server只对那些能加快数据查询速度的索引才能被选用。如果利用索引检索还不如顺序扫描速度快,SQL Server仍用扫描方法检索数据。建立不能被采用的索引只会增加系统的负担,降低检索速度。因此,可利用性是建立索引的首要条件。,例题,例6 为学生-课程数据库中的Student,Course,SC三个表建立索引。其中Student表按学号升序建唯一索引,Course表按课程号升序建唯一索引,SC表按学号升序和课程号降序建唯一索引。CREATE UNIQUE INDEX Stusno ON Student(Sno);CREATE UNIQUE INDEX Coucno ON Course(Cno);CREATE UNIQUE INDEX SCno ON SC(Sno ASC,Cno DESC);,二、删除索引,DROP INDEX;删除索引时,系统会从数据字典中删去有关该索引的描述。例7 删除Student表的Stusname索引。DROP INDEX Student.Stusname;,第3章 关系数据库标准语言SQL,3.1 SQL概述3.2 学生-课程数据库3.3 数据定义3.4 数据查询3.5 数据更新3.6 视图,3.4 查 询,3.4.1 单表查询3.4.2 连接查询3.4.3 嵌套查询3.4.4 集合查询3.4.5 SELECT 语句的一般格式,3.4 查 询,语句格式SELECT ALL|DISTINCT,FROM,WHERE GROUP BY HAVING ORDER BY ASC|DESC;,3.4 查 询,SELECT子句:指定要显示的属性列FROM子句:指定查询对象(基本表或视图)WHERE子句:指定查询条件 GROUP BY子句:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常会在每组中作用集函数。HAVING短语:筛选出只有满足指定条件的组ORDER BY子句:对查询结果表按指定列值的升序或降序排序,3.4 查 询,3.4.1 单表查询3.4.2 连接查询3.4.3 嵌套查询3.4.4 集合查询3.4.5 SELECT 语句的一般格式,3.4.1 单表查询,查询仅涉及一个表,是一种最简单的查询操作一、选择表中的若干列二、选择表中的若干元组三、对查询结果排序四、使用集函数五、对查询结果分组,查询指定列,例1 查询全体学生的学号与姓名。SELECT Sno,SnameFROM Student;例2 查询全体学生的姓名、学号、所在系。SELECT Sname,Sno,SdeptFROM Student;,查询全部列,例3 查询全体学生的详细记录。,SELECT Sno,Sname,Ssex,Sage,Sdept FROM Student;或SELECT*FROM Student;,3.查询经过计算的值,SELECT子句的为表达式算术表达式字符串常量函数列别名等,3.查询经过计算的值,例4 查全体学生的姓名及其出生年份。,SELECT Sname,2011-SageFROM Student;,3.查询经过计算的值,例5 查询全体学生的姓名、出生年份和所在系。在出生年份前面增加一个说明,在系名称后面增加一个“系”作为表示,SELECT Sname,出生年份:,2011-Sage,Sdept+系FROM Student;,例5.1 使用列别名改变查询结果的列标题,SELECT Sname 姓名,Year of Birth:生日标识,2011-Sage 生日,Sdept+系 系名FROM Student;,二、选择表中的若干元组,消除取值重复的行查询满足条件的元组,1.消除取值重复的行,在SELECT子句中使用DISTINCT短语,假设SC表中有下列数据 Sno Cno Grade-95001 1 92 95001 2 85 95001 3 88 95002 2 90 95002 3 80,ALL 与 DISTINCT,例6 查询选修了课程的学生学号。,(1)SELECT Sno FROM SC;或(默认 ALL)SELECT ALL Sno FROM SC;,(2)SELECT DISTINCT Sno FROM SC;,例题(续),注意 DISTINCT短语的作用范围是所有目标列例:查询选修课程的各种成绩错误的写法SELECT DISTINCT Cno,DISTINCT GradeFROM SC;正确的写法 SELECT DISTINCT Cno,Grade FROM SC;,2.查询满足条件的元组,WHERE子句常用的查询条件,(1)比较大小,在WHERE子句的中使用比较运算符=,=,!,!,逻辑运算符NOT+比较运算符例8 查询所有年龄在20岁以下的学生姓名及其年龄。,SELECT Sname,Sage FROM Student WHERE Sage=20;,(2)确定范围,使用谓词 BETWEEN AND NOT BETWEEN AND 例10 查询年龄在2023岁(包括20岁和23岁)之间的学生的姓名、系别和年龄。,SELECT Sname,Sdept,SageFROM StudentWHERE Sage BETWEEN 20 AND 23;,例题(续),例11 查询年龄不在2023岁之间的学生姓名、系别和年龄。,SELECT Sname,Sdept,SageFROM StudentWHERE Sage NOT BETWEEN 20 AND 23;,(3)确定集合,使用谓词 IN,NOT IN:用逗号分隔的一组取值例12查询信息系(IS)和计算机科学系(CS)学生的姓名和性别。,SELECT Sname,SsexFROM StudentWHERE Sdept IN(IS,CS);,(3)确定集合,例13查询既不是信息系又不是计算 机科学系的学生的姓名和性别。,SELECT Sname,SsexFROM Student WHERE Sdept NOT IN(IS,CS);,(4)字符串匹配,NOT LIKE ESCAPE:指定匹配模板 匹配模板:固定字符串或含通配符的字符串 当匹配模板为固定字符串时,可以用=运算符取代 LIKE 谓词 用!=或 运算符取代 NOT LIKE 谓词,通配符,%(百分号)代表任意长度(长度可以为0)的字符串例:a%b表示以a开头,以b结尾的任意长度的字符串。如acb,addgb,ab 等都满足该匹配串_(下横线)代表任意单个字符例:a_b表示以a开头,以b结尾的长度为3的任意字符串。如acb,afb等都满足该匹配串,ESCAPE 短语:,当用户要查询的字符串本身就含有%或 _ 时,要使用ESCAPE 短语对通配符进行转义。,例题,1)匹配模板为固定字符串 例14 查询学号为95001的学生的详细情况。SELECT*FROM Student WHERE Sno LIKE 95001;等价于:SELECT*FROM Student WHERE Sno=95001;,例题(续),2)匹配模板为含通配符的字符串例15 查询所有姓刘学生的姓名、学号和性别。,SELECT Sname,Sno,Ssex FROM Student WHERE Sname LIKE 刘%;,例题(续),匹配模板为含通配符的字符串(续)例16 查询姓“刘且全名为三个汉字的学生的姓名。,SELECT Sname FROM Student WHERE Sname LIKE 刘_;,备注:这里有两个_,关于SQL Server 2008字符集,SELECT COLLATIONPROPERTY(Chinese_PRC_Stroke_CI_AI_KS_WS,CodePage),查询结果:936 简体中文GBK 950 繁体中文BIG5 437 美国/加拿大英语 932 日文 949 韩文 866 俄文 65001 unicode UFT-8,数据库字符集为ASCII时,一个汉字需要两个_;当数据库字符集为GBK时,一个汉字只需要一个_,例题(续),匹配模板为含通配符的字符串(续)例17 查询名字中第2个字为“敏”字的学生的姓名和学号。,SELECT Sname,Sno FROM Student WHERE Sname LIKE _敏%;,例题(续),例18 查询所有不姓刘的学生姓名。SELECT Sname,Sno,Ssex FROM Student WHERE Sname NOT LIKE 刘%;,例题(续),3)使用换码字符将通配符转义为普通字符 例19 查询课程名称中包含“面向对象_C+课程”的课程号和学分。,SELECT Cno,Ccredit FROM Course WHERE Cname LIKE%面向对象_C+%,例题(续),SELECT Cno,Ccredit FROM Course WHERE Cname LIKE%面向对象 _C+%ESCAPE,例题(续),使用换码字符将通配符转义为普通字符(续)例20 查询以DB_开头,且倒数第3个字符为 i的课程的详细情况。,SELECT*FROM Course WHERE Cname LIKE DB_%i_ _ ESCAPE;,(5)涉及空值的查询,使用谓词 IS NULL 或 IS NOT NULL“IS NULL”不能用“=NULL”代替例21 有些课没有先修课程。查询没有先修课程的课程名称。,Select CnameFrom CourseWhere Cpno IS NULL,(6)多重条件查询,用逻辑运算符AND和 OR来联结多个查询条件 AND的优先级高于OR 可以用括号改变优先级可用来实现多种其他谓词 NOT IN NOT BETWEEN AND,例题,例23 查询计算机系年龄在20岁以下的学生姓名。,SELECT Sname FROM Student WHERE Sdept=CS AND Sage20;,改写例12,例12 查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。SELECT Sname,SsexFROM StudentWHERE Sdept IN(IS,MA,CS)可改写为:SELECT Sname,SsexFROM StudentWHERE Sdept=IS OR Sdept=MA OR Sdept=CS;,改写例10,例10 查询年龄在2023岁(包括20岁和23岁)之间的学生的姓名、系别和年龄。SELECT Sname,Sdept,SageFROM StudentWHERE Sage BETWEEN 20 AND 23;可改写为:SELECT Sname,Sdept,SageFROM Student WHERE Sage=20 AND Sage=23;,三、对查询结果排序,使用ORDER BY子句 可以按一个或多个属性列排序 升序:ASC;降序:DESC;缺省值为升序当排序列含空值时空值的显示顺序由具体系统实现来决定例如按升序排,含空值的元组最后显示按降序排,空值的元组最先显示各个系统的实现可以不同,只要保持一致即可,对查询结果排序(续),例24 查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列。,SELECT Sno,Grade FROM SC WHERE Cno=3 ORDER BY Grade DESC;,对查询结果排序(续),例25 查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。,SELECT*FROM Student ORDER BY Sdept,Sage DESC;,四、使用集函数,5类主要聚集函数计数COUNT(DISTINCT|ALL*)COUNT(DISTINCT|ALL)计算总和SUM(DISTINCT|ALL)计算平均值AVG(DISTINCT|ALL),使用集函数(续),求最大值MAX(DISTINCT|ALL)求最小值MIN(DISTINCT|ALL)DISTINCT短语:在计算时要取消指定列中的重复值ALL短语:不取消重复值ALL为缺省值,使用集函数(续),例26 查询学生总人数。例27 查询选修了课程的学生人数。,SELECT COUNT(DISTINCT Sno)FROM SC;注:用DISTINCT以避免重复计算学生人数,SELECT COUNT(*)FROM Student;,使用集函数(续),例28 计算2号课程的学生平均成绩。例29 查询选修3号课程的学生最高分数。,SELECT AVG(Grade)FROM SC WHERE Cno=2;,SELECT MAX(Grade)FROM SC WHER Cno=3;,五、对查询结果分组,使用GROUP BY子句分组 细化聚集函数的作用对象 未对查询结果分组,聚集函数将作用于整个查询结果 对查询结果分组后,聚集函数将分别作用于每个组,使用GROUP BY子句分组,例30 求各个课程号及相应的选课人数。,SELECT Cno,COUNT(Sno)FROM SC GROUP BY Cno;,使用GROUP BY子句分组,我们拥有下面这个 Orders 表:现在,我们希望查找每个客户的总金额(总订单)。,语句1:SELECT Customer,SUM(OrderPrice)FROM Orders,语句2:SELECT Customer,SUM(OrderPrice)FROM Orders GROUP BY Customer,课堂作业,使用GROUP BY子句分组,语句1:SELECT Customer,SUM(OrderPrice)FROM Orders,使用GROUP BY子句分组,语句2:SELECT Customer,SUM(OrderPrice)FROM Orders GROUP BY Customer,对查询结果分组(续),GROUP BY子句的作用对象是查询的中间结果表分组方法:按指定的一列或多列值分组,值相等的为一组;group by 是先排序后分组使用GROUP BY子句后,SELECT子句的列名列表中只能出现分组属性和聚集函数,或者说,select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面如果要用到group by 一般用到的就是“每”这个字,例如:每个部门有多少人 就要用到分组的技术,对查询结果分组(续),select Sno,Cno from SC group by Sno,-将会出现错误-消息 8120,级别 16,状态 1,第 1 行,选择列表中的列 SC.Cno 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。这就是我们需要注意的一点,如果在返回集字段中,这些字段要么就要包含在Group By语句的后面,作为分组的依据;要么就要被包含在聚合函数中。,select Sno as 学号,COUNT(*)as 选课门数 from SC group by Sno,使用HAVING短语筛选最终输出结果,例31 查询选修了2门及以上课程的学生学号。,SELECT Sno FROM SC GROUP BY Sno HAVING COUNT(*)2;,例题,例32 查询有2门及以上课程是85分以上的 学生的学号及(85分以上的)课程数,SELECT Sno,COUNT(*)FROM SC WHERE Grade=85 GROUP BY Sno HAVING COUNT(*)=2;,使用HAVING短语筛选最终输出结果,只有满足HAVING短语指定条件的组才输出HAVING短语与WHERE子句的区别:作用对象不同WHERE子句作用于基表或视图,从中选择满足条件的元组。HAVING短语作用于组,从中选择满足条件的组。,3.4 查 询,3.4.1 单表查询3.4.2 连接查询3.4.3 嵌套查询3.4.4 集合查询3.4.5 SELECT 语句的一般格式,3.4.2 连接查询,同时涉及多个表的查询称为连接查询用来连接两个表的条件称为连接条件或连接谓词 一般格式:.比较运算符:=、=、.BETWEEN.AND.,连接查询(续),连接字段连接谓词中的列名称为连接字段连接条件中的各连接字段类型必须是可比的,但不必是相同的,连接操作的执行过程,嵌套循环法(NESTED-LOOP)首先在表1中找到第一个元组,然后从头开始扫描表2,逐一查找满足连接件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。表2全部查找完后,再找表1中第二个元组,然后再从头开始扫描表2,逐一查找满足连接条件的元组,找到后就将表1中的第二个元组与该元组拼接起来,形成结果表中一个元组。重复上述操作,直到表1中的全部元组都处理完毕,嵌套循环连接,基于元组的嵌套循环连接Result=;/*初始化结果集合*/For each tuple s in SFor each tuple r in RIf r.B=s.B then/*元组r和元组s满足连接条件*/Join r and s as tuple t;Output t into Result;/*输出连接结果元组*/EndifEndforEndforReturn Result,嵌套循环连接,上面基于元组的嵌套循环连接算法中,对于循环外层的关系,通常称为外关系,而对循环内层的关系称为内关系。在执行嵌套循环连接时,仅对外关系进行1次读取操作,而对内关系则需要进行反复读取操作。如果不进行优化的话,这种基于元组的执行代价很大,以磁盘IO计算最多可能达到Card(R)*Card(S)。因此,通常对这种算法进行修改,以减少嵌套循环连接的磁盘IO代价。一种方法是使用连接属性上的索引,以减少参与连接元组的数量,称为“索引嵌套循环连接”,排序合并法(SORT-MERGE),常用于=连接首先按连接属性对表1和表2排序对表1的第一个元组,从头开始扫描表2,顺序查找满足连接条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。当遇到表2中第一条大于表1连接字段值的元组时,对表2的查询不再继续,排序合并法,找到表1的第二条元组,然后从刚才的中断点处继续顺序扫描表2,查找满足连接条件的元组,找到后就将表1中的第二个元组与该元组拼接起来,形成结果表中一个元组。直接遇到表2中大于表1连接字段值的元组时,对表2的查询不再继续重复上述操作,直到表1或表2中的全部元组都处理完毕为止,连接查询(续),SQL中连接查询的主要类型 广义笛卡尔积 等值连接(含自然连接)非等值连接查询 自身连接查询 外连接查询 复合条件连接查询,一、广义笛卡尔积,不带连接谓词的连接 很少使用例:SELECT Student.*,SC.*FROM Student,SC,二、等值与非等值连接查询,等值连接、自然连接、非等值连接例32 查询每个学生及其选修课程的情况。,SELECT Student.*,SC.*FROM Student,SCWHERE Student.Sno=SC.Sno;,等值连接,连接运算符为=的连接操作.=.任何子句中引用表1和表2中同名属性时,都必须加表名前缀。引用唯一属性名时可以加也可以省略表名前缀。,自然连接,等值连接的一种特殊情况,把目标列中重复的属性列去掉。例33 对例32用自然连接完成。SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade FROM Student,SC WHERE Student.Sno=SC.Sno;,非等值连接查询,连接运算符 不是=的连接操作.比较运算符:、=、.BETWEEN.AND.,三、自身连接,一个表与其自己进行连接,称为表的自身连接需要给表起别名以示区别由于所有属性名都是同名属性,因此必须使用别名前缀,自身连接(续),例34 查询每一门课的间接先修课(即先修课的先修课),SELECT FIRST.Cno,SECOND.Cpno FROM Course FIRST,Course SECOND WHERE FIRST.Cpno=SECOND.Cno;,四、外连接(Outer Join),外连接与普通连接的区别普通连接操作只输出满足连接条件的元组外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出,外连接(续),例 33 查询每个学生及其选修课程的情况包括没有选修课程的学生-用外连接操作,SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade FROM Student LEFT JOIN SC ON(Student.Sno=SC.Sno),五、复合条件连接,WHERE子句中含多个连接条件时,称为复合条件连接例35查询选修2号课程且成绩在86分以上的所有学生的学号、姓名,SELECT Student.Sno,student.SnameFROM Student,SCWHERE Student.Sno=SC.Sno/*连接谓词*/AND SC.Cno=2/*其他限定条件*/AND SC.Grade 86;/*其他限定条件*/,多表连接,例36 查询每个学生的姓名、选修课程名及成绩。,SELECT Sname,Cname,Grade FROM Student,SC,Course WHERE Student.Sno=SC.Sno and SC.Cno=Course.Cno;,3.4 查 询,3.4.1 单表查询3.4.2 连接查询3.4.3 嵌套查询3.4.4 集合查询3.4.5 SELECT 语句的一般格式,3.4.3 嵌套查询,嵌套查询概述嵌套查询分类嵌套查询求解方法引出子查询的谓词,嵌套查询(续),嵌套查询概述一个SELECT-FROM-WHERE语句称为一个查询块将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询,嵌套查询(续),SELECT Sname外层查询/父查询 FROM StudentWHERE Sno IN(SELECT Sno 内层查询/子查询 FROM SC WHERE Cno=2);,例 查询选修2号课程的学生信息。,嵌套查询(续),子查询的限制不能使用ORDER BY子句层层嵌套方式反映了 SQL语言的结构化有些嵌套查询可以用连接运算替代,An Introduction to Database System,嵌套查询分类,不相关子查询子查询的查询条件不依赖于父查询相关子查询子查询的查询条件依赖于父查询,嵌套查询求解方法,不相关子查询是由里向外逐层处理。即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。,嵌套查询求解方法(续),相关子查询首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表;然后再取外层表的下一个元组;重复这一过程,直至外层表全部检查完为止。,引出子查询的谓词,带有IN谓词的子查询带有比较运算符的子查询带有ANY或ALL谓词的子查询带有EXISTS谓词的子查询,一、带有IN谓词的子查询,例37 查询与“刘晨”在同一个系学习的学生。此查询要求可以分步来完成,确定“刘晨”所在系名 SELECT Sdept FROM Student WHERE Sname=刘晨 结果为:Sdept IS,带有IN谓词的子查询(续),查找所有在IS系学习的学生。SELECT Sno,Sname,Sdept FROM Student WHERE Sdept=IS;结果为:Sno Sname Sdept95001 刘晨 IS95004 张立 IS,构造嵌套查询,将第一步查询嵌入到第二步查询的条件中 SELECT Sno,Sname,Sdept FROM Student WHERE Sdept IN(SELECT Sdept FROM Student WHERE Sname=刘晨);此查询为不相关子查询。DBMS求解该查询时也是分步去做的。,带有IN谓词的子查询(续),用自身连接完成本查询要求 SELECT S1.Sno,S1.Sname,S1.Sdept FROM Student S1,Student S2 WHERE S1.Sdept=S2.Sdept AND S2.Sname=刘晨;,带有IN谓词的子查询(续),父查询和子查询中的表均可以定义别名 SELECT Sno,Sname,Sdept FROM Student S1 WHERE S1.Sdept IN(SELECT Sdept FROM Student S2 WHERE S2.Sname=刘晨);,带有IN谓词的子查询(续),例38查询选修了课程名为“信息系统”的学生学号和姓名,SELECT Sno,Sname 最后在Student关系中 FROM Student 取出Sno和Sname WHERE Sno IN(SELECT Sno 然后在SC关系中找出选 FROM SC 修了3号课程的学生学号 WHERE Cno IN(SELECT Cno 首先在Course关系中找出“信 FROM Course 息系统”的课程号,结果为3号 WHERE Cname=信息系统);,带有IN谓词的子查询(续),用连接查询 SELECT Sno,Sname FROM Student,SC,Course WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno AND Course.Cname=信息系统;,二、带有比较运算符的子查询,当能确切知道内层查询返回单值时,可用比较运算符(,=,)。与ANY或ALL谓词配合使用,带有比较运算符的子查询(续),例:假设一个学生只可能在一个系学习,并且必须属于一个系,则在例37可以用=代替IN:SELECT Sno,Sname,Sdept FROM Student WHERE Sdept=(SELECT Sdept FROM Student WHERE Sname=刘晨);,带有比较运算符的子查询(续),例:找出每个学生超过他自己选修课程平均成绩的课程号Selec