嵌套查询

嵌套查询

带有IN谓词的嵌套查询

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

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

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

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

select s1.Sno, s1.Sname, s1.Sdept
from Student s1, Student s2
where s1.Sdept = s2.Sdept and s2.Sname = '刘晨';

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

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

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

带有比较运算符的子查询

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

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

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

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

select Student.*, Cno
from SC x, Student
where 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.Sage
from Student s1
where s1.Sdept <> 'CS' and s1.Sage < any (
        select Sage
        from Student  s2
        where s2.Sdept = 'CS'
    );

使用聚集函数说明
select Sname, Sage
from Student
where Sage < (
        select max(Sage)
        from Student
        where Sdept = 'CS'
    ) and
    Sdept != 'CS';

带有exists 谓词的子查询

exists代表存在量词

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

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

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

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

select Sname
from Student, SC
where Student.Sno = SC.Sno and Cno = 2;

使用in子查询实现

select Sname
from Student x
where Sno in (
        select Sno
        from SC
        where Cno = 2
    );

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

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

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值