3.答:
R1 A B C 3 2 F 1 7 B 4 C 4 2 7 7 B 7 5 7 F R2 B R3 A R4 A
2 4 6 7 4 4 4.答: W1 R.A R.B R.C 3 2 1 7 4 4
W3 R.A R.B R.C 2 4 6 7 4 4
4 5 2 4 6 2 4 9 4 7 3 2 1 7 4 5
7
4
7
W2 R.A R.B R.C S.D S.F
2 4 6 3 5 2 4 6 4 7 7 4 4 3 5 7 4 4 3 7 W4 R.A R.B R.C 2 4 6
3 2 1
第3章 关系数据库语言SQL
3.1 基本内容分析
3.1.1 本章重要概念
(1)SQL数据库的体系结构,SQL的组成。
(2)SQL的数据定义:SQL模式、基本表和索引的创建和撤销。
(3)SQL的数据查询;SELECT语句的句法,SELECT语句的三种形式及各种限定,基本表的联接操作,SQL3中的递归查询。
(4)SQL的数据更新:插入、删除和修改语句。 (5)视图的创建和撤消,对视图更新操作的限制。
(6)嵌入式SQL:预处理方式,使用规定,使用技术,卷游标,动态SQL语句。 3.1.2 本章的重点篇幅
(1)教材中P97的例3.8(SELECT语句)。
(2)教材中P123的例3.31和P123的例3.32(嵌入式SQL)。 3.1.3 重要内容分析
SELECT语句是SQL的核心内容,对于该语句考生应掌握下列内容。 1.SELECT语句的来历
在关系代数中最常用的式子是下列表达式:
πA1,…,An(σF(R1×…×Rm))
这里R1、…、Rm为关系,F是公式,A1、…、An为属性。
针对上述表达式,SQL为此设计了SELECT—FROM—WHERE句型: SELECT A1,…,An FROM R1,…,Rm WHERE F
这个句型是从关系代数表达式演变来的,但WHERE子句中的条件表达式F要比关系代数中公式更灵活。
2.SELECT语句中出现的基本表名,应理解为基本表中的元组变量,而列名应理解为元组分量。
3.SELECT语句的语义有三种情况,下面以学生表S(S#,SNAME,AGE,SEX)为例说明。 第一种情况:SELECT语句中未使用分组子句,也未使用聚合操作,那么SELECT子句的语义是对查询的结果执行投影操作。譬如:
SELECT S#,SNAME FROM S
WHERE SEX='M';
第二种情况:SELECT语句中未使用分组子句,但在SELECT子句中使用了聚合操作,此时SELECT子句的语义是对查询结果执行聚合操作。譬如:
SELECT COUNT(*),AVG(AGE) FROM S
WHERE SEX='M';
该语句是求男同学的人数和平均年龄。
第三种情况:SELECT语句使用了分组子句和聚合操作(有分组子句时必有聚合操作),此时SELECT子句的语义是对查询结果的每一分组去做聚合操作。譬如:
SELECT AGE,COUNT(*) FROM S WHERE SEX='M'
GROUP BY AGE;
该语句是求男同学每一年龄的人数。
4.SELECT语句中使用分组子句的先决条件是要有聚合操作。但执行聚合操作不一定要用分组子句。譬如求男同学的人数,此时聚合值只有一个,因此不必分组。
但同一个聚合操作的值有多个时,必须使用分组子句。譬如求每一年龄的学生人数。此时聚合值有多个,与年龄有关,因此必须分组。
3.2 教材中习题3的解答
3.1 名词解释
·基本表:实际存储在数据库中的表,称为基本表。
·视图:是从基本表或其他视图中导出的表,它本身不独立存储在数据库中,也就是数据库中只存放视图的定义而不存放视图的数据。
·实表:是对基本表的别称。 ·虚表:是对视图的别称。
·相关子查询:SELECT语句嵌套时,子查询中查询条件依赖于外层查询中的值,因此子查询要反复求值供外层查询使用。这种子查询称为相关子查询。
·联接查询:查询时要从多个基本表中提取数据,此时把多个基本表写在同一层的FROM子句中,这种查询形式称为联接查询。
·嵌套查询:查询时要从多个基本表中提取数据,此时把多个基本表分别放在不同层次上的FROM子句中,这种查询形式称为嵌套查询。
·交互式SQL:在终端交互方式使用的SQL语言。
·嵌入式SQL:嵌入在高级语言的程序中使用的SQL语言。
·共享变量:嵌入的SQL语句和主语言语句间传递信息的变量,称为共享变量。共享变量先由主语言程序定义,再用SQL的说明语句说明,然后SQL语句就可使用这些变量。
·游标:游标是与某一查询相联系的符号名。游标有游标关系和游标指针两层含义。在游标打开时,游标(指针)指向查询结果的第一个记录之前。
·卷游标:在游标推进时,可以进退自如的游标。 3.2 对于教学数据库的三个基本表 S(S#,SNAME,AGE,SEX) SC(S#,C#,GRADE)
C(C#,CNAME,TEACHER)
试用SQL的查询语句表达下列查询:
①检索LIU老师所授课程的课程号和课程名。 ②检索年龄大于23岁的男学生的学号和姓名。
③检索学号为S3学生所学课程的课程名与任课教师名。
④检索至少选修LIU老师所授课程中一门课程的女学生姓名。 ⑤检索WANG同学不学的课程的课程号。 ⑥检索至少选修两门课程的学生学号。
⑦检索全部学生都选修的课程的课程号与课程名。 ⑧检索选修课程包含LIU老师所授课程的学生学号。 解:① SELECT C#, CNAME
FROM C
WHERE TNAME=’LIU’; ② SELECT S#, SNAME
FROM S
WHERE AGE>23 AND SEX=’M’; ③ SELECT CNAME,TEACHER
FROM SC, C
WHERE SC.C#=C.C# AND S#=’S3’;
④ SELECT SNAME (联接查询方式)
FROM S, SC, C
WHERE S.S#=SC.S# AND SC.C#=C.C#
AND SEX=’F’ AND TNAME=’LIU’;
或:SELECT SNAME (嵌套查询方式)
FROM S
WHERE SEX=’F’
AND S# IN (SELECT S# FROM SC
WHERE C# IN (SELECT C#
FROM C
WHERE TNAME=’LIU’));
或:SELECT SNAME (存在量词方式)
FROM S
WHERE SEX=’F’
AND EXISTS (SELECT *
FROM SC
WHERE SC.S#=S.S#
AND EXISTS (SELECT * FROM C WHERE C.C#=SC.C#
AND TNAME=’LIU’));
⑤ SELECT C# FROM C
WHERE NOT EXISTS (SELECT * FROM S, SC WHERE S.S#=SC.S# AND SC.C#=C.C# AND SNAME=’WANG’); ⑥ SELECT DISTINCT X.S#
FROM SC AS X, SC AS Y
WHERE X.S#=Y.S# AND X.C#!=Y.C#; ⑦ SELECT C#, CNAME FROM C
WHERE NOT EXISTS
(SELECT *
FROM S
WHERE NOT EXISTS
(SELECT * FROM SC WHERE S#=S.S# AND C#=C.C#));
在1974年的SYSTEM R系统中,曾使用过“集合包含”的语法,即 (集合1)CONTAINS(集合2) 用这种语法也能写出本题的SELECT语句,即: SELECT C#,CNAME FROM C WHERE (SELECT S# FROM SC WHERE C#=C.C#) CONTAINS (SELECT S# FROM S); 由于判断“(集合1)CONTAINS(集合2)”与“NOT EXISTS((集合2)EXCEPT(集合1))”是等价的,因此本题的SELECT语句也能这样写:
SELECT C#,CNAME FROM C WHERE NOT EXISTS
((SELECT S# FROM S)
EXCEPT
(SELECT S# FROM SC WHERE C#=C.C#));
⑧ SELECT DISTINCT S# FROM SC AS X
WHERE NOT EXISTS (SELECT * FROM C WHERE TNAME=’LIU’ AND NOT EXISTS (SELECT * FROM SC AS Y WHERE Y.S#=X.S# AND Y.C#=C.C#)); 与⑦类似,本题的SELECT语句也能这样写: SELECT DISTINCT S#
FROM SC X WHERE NOT EXISTS
((SELECT C# FROM C WHERE TEACHER=’LIU’)
EXCEPT
(SELECT C# FROM SC Y WHERE Y.S#=X.S#));
3.3 对于第3.2题中的8个查询语句,试给出SELECT语句的图示形式。
解:为了说明问题,这里先用高级语言的算法形式表示其执行过程,再给出图示形式。 下面给出④、⑤、⑦、⑧的算法及图示形式。
④ 如果把三个关系S、SC、C看成三个文件,那么可以看出这个查询语句的SELECT语句实际上是一个三重循环。从而可得这个查询的算法形式如下:
for关系S的每个元组do