嵌套查询

来源:互联网 发布:冰川网络官网 编辑:程序博客网 时间:2024/05/22 14:38

嵌套查询

带有IN谓词的嵌套查询

查询与刘晨同在一个系学习的学生

可以分成两步进行查询,首先确定刘晨所在的系名a,再在Student表中筛选出系名为a的数据,显示出来

select Sno, Sname, Sdeptfrom Studentwhere Sdept in (        select Sdept        from Student        where Sname = '刘晨'    );

注意不能使用Sdept = 应为刘晨不是主键,查询出来的结果是一个集合不是一个元素,如果有重名的刘晨就惨了。
使用内连接完成:

select s1.Sno, s1.Sname, s1.Sdeptfrom Student s1, Student s2where s1.Sdept = s2.Sdept and s2.Sname = '刘晨';

查询选择了课程2的学生信息

  • 通过连接操作查询
select Student.*from Student, SCwhere Student.Sno = SC.Sno and Cno = 2;
  • 通过子查询进行
select Student.*from Studentwhere Sno in (        select Sno        from SC        where Cno = 2     );

注意:
子查询的select语句中不允许使用order by语句,order by语句只能用于对最终查询结果进行排序。
有些嵌套查询可以用连接查询进行替代,但是有些是无法进行替代的。
查询时涉及到多个查询的时候,使用多个查询层次分明。但是连接操作效率更高,因此能够使用连接操作完成的话,尽量使用连接。
根据子查询是否依赖于父查询可以分为相关子查询和不相关子查询,前面的例子都是不相关的子查询

带有比较运算符的子查询

确切的知道内层查询返回的单个元素不是元素集合的时候,可以使用比较运算符

找出每个学生超过他自己选修平均成绩的课程号

select Sno, Cnofrom SC xwhere x.Grade > (        select avg(Grade)        from SC y        where y.Sno = x.Sno    );

注意这是一个相关查询,相关查询通过 传入内查询的x.Sno隐含了对内部查询的分组,因此使用avg得出的是该学生的一个平均成绩
如果要显示学生姓名等信息,可以加上一个连接查询学生信息

select Student.*, Cnofrom SC x, Studentwhere x.Grade > (        select avg(Grade)        from SC y        where y.Sno = x.Sno    ) and    Student.Sno = x.Sno;

带有ANY(SOME)或ALL谓词的子查询

子查询返回的是一个元素集合的话,这是由不能使用比较运算符,使用ANY SOME ALL 谓词

查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄

select s1.Sname, s1.Sagefrom Student s1where s1.Sdept <> 'CS' and s1.Sage < any (        select Sage        from Student  s2        where s2.Sdept = 'CS'    );使用聚集函数说明select Sname, Sagefrom Studentwhere Sage < (        select max(Sage)        from Student        where Sdept = 'CS'    ) and    Sdept != 'CS';

带有exists 谓词的子查询

exists代表存在量词

查询所有选修了课程2的学生姓名

使用exists谓词的子查询实现,用来表述是否在某个属性的集合

select Snamefrom Studentwhere exists (        select *         from SC        where         Sno = Student.Sno and Cno = 2    );

注意:
使用exists关键字更加的容易被理解,更接近于自然语义
有exists引出的子查询,其目标表达式通常使用*, 因为exists的子查询只返回真或者假,给出列名是没有任何意义的。
使用连接查询实现

select Snamefrom Student, SCwhere Student.Sno = SC.Sno and Cno = 2;

使用in子查询实现

select Snamefrom Student xwhere Sno in (        select Sno        from SC        where Cno = 2    );

查询选修了全部课程的学生

SQL中没有全程量词,因此可以将全称量词构成的命题转换为存在量词构成的命题。
实现的SQL语句可以是如下的代码:

select Snamefrom Studentwhere not exists (         select *         from Course            where not exists (             select *             from SC             where Sno = Student.Sno and                      Cno = Course.Cno         )    );

学习《数据库系统概论》笔记

0 0