当前位置:   article > 正文

数据库:嵌套查询_查询和李勇在同一个系的同学的姓名以及选修课程名

查询和李勇在同一个系的同学的姓名以及选修课程名

[例 3.55] 查询与“李勇”在同一个系学习的学生。

select *
from student
where Sdept in(
      select Sdept
	  from student
	  where Sname='李勇');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
也可以用自身连接

select *		
from student s1,Student s2
where s1.Sdept=s2.Sdept and s2.Sname='李勇'
  • 1
  • 2
  • 3

在这里插入图片描述

[例 3.56]查询选修了课程名为“数据库”的学生学号和姓名

select Sno,Sname
from student
where Sno in(
		     select Sno
			 from sc
			 where Cno in(
							select Cno
							from course
							where Cname='数据库'));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述
这个语句的执行顺序是

  1. 先找到course表中选择了数据库的课程号。结果为1号。
  2. 在sc表中找出选修了1号课的学生的学号。
  3. 在student表中取出sno和sname
    例子55和例子66都是由内而外的查询,子查询的条件不依赖父查询的条件,这就是不相关子查询。

本例子也可以有等值连接完成。

select student.Sno,Sname
from course,student,sc
where sc.Sno=Student.Sno and	
		sc.cno=course.cno and
		course.cname='数据库'
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

[例 3.57 ]找出每个学生超过他选修课程平均成绩的课程号。

select Sno,Cno
from SC x
where Grade>=(
				select AVG(Grade)
				from SC y
				where x.Sno=y.Sno
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述
这里就是因为子查询与父查询相关,这是相关子查询。相关子查询类似c语言中的二重循环。
1.将表sc(一个x,一个为y)x中的第一个元组,红色箭头所示,将他的sno传递给内层循环
select AVG(Grade)
from SC
where sno=‘201215121’
2.然后执行内层相当于求该学生的平均成绩。
((92+85+88)/3=88(grade为整数这里取整数))
3.在返回外层x的成绩与内层循环求出来的平均成绩作比较。(即92与88作比较)然后进行下一个元组(黑色箭头)重复执行1.
在这里插入图片描述
就是相当于这样的格式两列相比较。
在这里插入图片描述

带有ALL或者ANY谓词的子查询

在这里插入图片描述

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

select Sname,Sage
from student
where  Sdept!='cs' AND Sage < ANY(
					select Sage
					from student
					where Sdept='CS'
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述
就是再找计算机系中的年龄最大值。

[例 3.59] 查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名及年龄。

select Sname,Sage
from student
where  Sdept!='cs' AND Sage < ALL(
					select Sage
					from student
					where Sdept='CS'
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述
就是找最小值。

带有EXIST谓词的子查询

1.只返回true或者false;
2.当内层查询里有数据时,为true,否则为false;
3.一般内层查询的列只用*,因为无论写什么,他只返回一个true 或者 false。给出列名无意义。
4.not exists 相当于exist取反。

[例 3.60]查询所有选修了1号课程的学生姓名。

select Sname,Sno
from student 
where EXISTS(
		select *
		from SC
		where Sno=student.Sno AND Cno='1'
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

[例 3.61] 查询没有选修1号课程的学生姓名。

select Sname,Sno
from student 
where NOT EXISTS(
		select *
		from SC
		where Sno=student.Sno AND Cno='1'
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述
用存在量词实现全称量词(sql中没有全称量词)
在这里插入图片描述

[例 3.62] 查询选修了全部课程的学生姓名。

select Sname
from student
where NOT EXISTS (
					select *
					from course
					where NOT EXISTS(
										select *
										from sc
										where sc.Cno=course.cno AND student.Sno=sc.Sno))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述
我这是创建了一个学生选修了全部课程。例子里并没有这样的学生。
这就是一个三重循环,最外层遍历学生,次外层遍历学生所选的课程,内层判断。当一个学生选择了全部的课程,那么他内层给外层的返回值全是f然后次外层给外层返回一个t。当有课没选时,内层给外层的返回值就有了t,这是或的关系,即次外层的整体值为t,返回给最外层的值就为f。

[例 3.63]查询至少选修了学生201215121选修的全部课程的学生号码。

select Sno
from student
where NOT EXISTS(
				select *
				from course,sc
				where  sc.Sno='201215121' AND NOT EXISTS(
														select *
														from sc sc2
														where sc2.Sno=student.Sno AND sc2.Cno=sc.Cno));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述

这个全称量词和蕴涵转换有一点绕,但是多看,多体会还是可以的。前面的in,any,all还是比较简单的,多思考过程,过程搞清楚了,就明白了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/498797
推荐阅读
相关标签
  

闽ICP备14008679号