[not] exists 和 in

前置:https://blog.csdn.net/Jaihk662/article/details/80144010

注:所有的下划线+斜体语句都是非必须语句


在提到exist之前,先再看看 in 语句:

现有两张表:第一张是学生信息(infer),第二张是学生选课及成绩(sc)


执行语句如下:

select * from infer
where st in (select st from sc
	     where sc.st = infer.st and sc.ct = '003');

检索选修了003号课程的学生的信息

其中 in 语句的具体过程如下:

步骤①:先执行子查询,求出所有的满足条件的学号映射如下:


步骤②:将子查询得到的学号映射作为一个table,与原有的学生信息(infer)表进行笛卡尔积,结果如下:


步骤③:再从中挑出所有满足 infer.st = sc.st 条件的元组(图片中深蓝色的两条)

从上面具体步骤可以看出,通俗来讲in语句的复杂度大概是O(n*m)的,其中n为外表(infer)大小,m为内表(sc)大小


再说 exists 子查询:

SQL语句:not exists (子查询)

语言描述:对于每一个元组,检查满足子查询条件的元组存不存在,如果存在就返回1,否则返回0

还是上面那张表,还是那个例子(检索选修了003号课程的学生的信息):

select * from infer
where exists (select * from sc
	      where sc.st = infer.st and sc.ct = '003');

当然,这个语句和上面的那个 in 语句起到的效果一模一样

但是它们的步骤却不同,exists语句具体过程如下:

步骤①:先查外层的表(infer):


步骤②:暴力外层表中的每一个元组,执行子查询中的语句,判断满足要求的元组是否存在

步骤③:如果存在返回1,否则返回0,如果返回的是1的话,则该行结果保留,如果返回的是0的话,删除该行

从上面具体步骤可以看出,整个过程就是exists执行了infer.size()次

总结:和 in 语句相比,它们的作用其实一样,但它们的具体步骤不一样

当内表(sc)比外表(infer)大很多时,使用 exists 语句要更优,反之使用 in 语句更优


not exists 简要介绍:

很容易理解,就是和exists相反,如果不存在返回1,否则返回0,但是 not exists 却可以实现很多新功能

例如:检索学过001号教师主讲的所有课程的所有同学的姓名

Select Sname From Student
Where not exists (Select * From Course
Where Course.Tc = ‘001’ and not exists (Select * From SC
Where St = Student.St and Ct = Course.Ct)); 

语言描述:不存在有一门001号教师主讲的课程该同学没学过



猜你喜欢

转载自blog.csdn.net/jaihk662/article/details/80146943
今日推荐