SC.Sno=Student.Sno; 4 复合条件连接 【例37】
【例38】 查询每个学生的学号(Sno)、姓名(Sname)、选修的课程名(Cname)及成绩(Grade)。
本查询涉及到三个表的连接操作,完成该查询的SQL语句如下: SELECT Student.Sno, Sname, Cname, Grade FROM Student, SC, Course
WHERE Student.Sno= SC.Sno AND SC.Cno=Course.Cno;
(二)嵌套查询
1 带谓词IN的嵌套查询
【例39】查询与“李伟”在同一个系学习的学生学号(Sno)、姓名(Sname)和系名(Sdept)。 该查询可构造嵌套查询实现,其SQL语句如下: SELECT Sno, Sname, Sdept FROM Student WHERE Sdept IN (SELECT Sdept FROM Student
WHERE Sname=’李伟’);
说明:本例中的查询也可以用自身连接来完成,其SQL语句如下: SELECT A.Sno , A.Sname , A.Sdept FROM Student A , Student B
WHERE A.Sdept=B.Sdept AND B.Sname=’李伟’;
【例40】 查询选修了编号为“2”的课程的学生姓名(Sname)和所在系(Sdept)。
SELECT Sname, Sdept FROM Students WHERE Sno IN (SELECT Sno FROM SC WHERE Cno='2');
【例41】 查询选修了课程名为“数据结构”的学生学号(Sno)和姓名(Sname)。
本查询涉及学号、姓名和课程名(Cname)三个属性。学号和姓名存放在Student表中,课程名的存放在Course表中,但Student与Course两个表之间没有公共属性,必须通过SC表建立它们之间的联系。所以本查询实际上涉及三个关系的连接操作。
SELECT Sno, Sname /* ③最后在Studen关系中 */ FROM Student /* 取出Sno和Sname */ WHERE Sno IN
11
(SELECT Sno /*② 然后在SC关系中找出 */ FROM SC /*选修了3号课程的学生学号*/ WHERE Cno IN
(SELECT Cno /*① 首先在Course关系中 */ FROM Course /*找出“数据结构”的课程号*/ WHERE Cname = ‘数据结构’)); /*结果为5号 */ 说明:本查询同样可以用连接查询实现: SELECT S.Sno, Sname
FROM Student S, SC R, Course C
WHERE S.Sno=R.Sno AND R.Cno=C.Cno AND C.Cname='数据结构'; 2 带有比较运算符的嵌套查询
【例42】 将例39改为带有比较运算符的嵌套查询。由于一个学生只可能在一个系学习,因此子查询的结果是一个值,因此可以用=代替IN,其SQL语句如下:
SELECT Sno , Sname, Sdept FROM Student WHERE Sdept =
(SELECT Sdept FROM Student
WHERE Sname=’李伟’); 3 带谓词ANY或ALL的嵌套查询
【例43】 查询计算机系(CS)的不超过自动化系所有学生的年龄的学生姓名(Sname)和年龄(Sage)。其查询命令为
SELECT Sname, Sage FROM Student WHERE Sdept<>'CS'
AND Sage<=ALL (SELECT Sage
FROM Student WHERE Sdept= 'CS');
说明:本查询也可以用集函数来实现。其SQL语句如下: SELECT Sname, Sage FROM Student WHERE Sdept<>'CS'
AND Sage<= (SELECT MIN(Sage)
FROM Student WHERE Sdept='CS'); 4 带谓词EXISTS的嵌套查询
【例44】 查询所有选修了编号为“1”课程的学生姓名(Sname)和所在系(Sdept)。 本查询的SQL语句是:
12
SELECT Sname, Sdept FROM Student WHERE EXISTS (SELECT * FROM SC
WHERE Sno=Student.Sno AND Cno='1');
【例45】 将例39改为带谓词EXISTS的查询,其SQL语句如下 SELECT Sno, Sname, Sdept FROM Student A WHERE EXISTS (SELECT * FROM Students B
WHERE B.Sdept=A.Sdept AND B.Sname=’李伟’); 【例46】 查询选修了所有课程的学生姓名(Sname)和所在系。
由于没有全称量词,可将题目的意思转换成等价的用存在量词的形式:查询这样的学生,没有一门课程是他不选修的。其SQL语句为:
SELECT Sname, Sdept FROM Student WHERE NOT EXISTS (SELECT * FROM Course WHERE NOT EXISTS
(SELECT * FROM SC WHERE Sno=Student.Sno
AND Cno=Course.Cno));
(三)集合查询
【例48】 查询计算机系(CS)的学生或年龄不大于20岁的学生信息。 SELECT * FROM Student WHERE Sdept='CS' UNION SELECT * FROM Student WHERE Sage<=20;
【例49】 查询计算机系(CS)的学生且年龄不大于20岁的学生的交集,这实际上就是查询数学系中年龄不大于20岁的学生。
SELECT * FROM Student
WHERE Sdept='CS' AND Sage<=20;
13
【例50】 查询计算机系的学生与年龄不大于20岁的学生的差集。 本查询的等价说法是,查询数学系中年龄大于20岁的学生。 SELECT * FROM Student
WHERE Sdept='CS' AND Sage>20;
14
2.4实验四 SQL的数据更新
一、实验目的和要求
掌握SQL数据插入、修改和删除语句的一般格式和使用方法。
二、实验内容及步骤 1.插入数据
【题4-01】 将学生陈冬的信息(学号:200215128;姓名:陈冬;性别:男;所在系:IS;年龄:18岁)插入到Student表中。
INSERT
INTO Student(Sno,Sname,Ssex,Sdept,Sage) VALUES(‘200215128’,’陈冬’,’男’,’IS’,18); 或 INSERT
INTO Student(Sno,Sname,Ssex,Sage,Sdept) VALUES(‘200215128’,’陈冬’,’男’,18,’IS’); 或INSERT INTO Student
VALUES(‘200215128’,’陈冬’,’男’,18,’IS’);
【题4-02】 插入一条选课记录(’200215128’,’1’) INSERT
INTO SC(Sno,Cno) VALUES(‘200215128’,’1’);
【题4-03】 设数据库中已有一个关系History_Student,其关系模式与Student完全一样,试将关系Student中的所有元组插入到关系History_Student中去,其SQL命令为:
INSERT
INTO History_Student SELECT * FROM Student;
【例4-04】对每一个系,求学生的平均年龄,并把结果存入表文件Dept_age中。Dept_age表文件属性为:Sdept(系名)、Avg_age(平均年龄)。
INSERT
INTO Dept_age(Sdept,Avg_age) SELECT Sdept,AVG(Sage) FROM Student
15