MySQL数据库代码中,两个exists语句同时出现同一查询语句中时,怎么理解,,越详细越好。,

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL数据库代码中,两个exists语句同时出现同一查询语句中时,怎么理解,,越详细越好。,相关的知识,希望对你有一定的参考价值。

mysql数据库代码中,两个exists语句同时出现同一查询语句中时,怎么理解,,越详细越好。,比如这个例题

在sql语言里"存在"exists子句是非常不好理解的。

exists子句有两种用法,一种为独立exists子查询,另一种是父子关联子查询。前者对父查询不构成筛选作用,子查询若果有记录存在的话则输出所有的父查询记录集,反之则父查询输出空记录集。后者会对父查询构成筛选作用,不使用not关键字的情况下输出父查询中与子查询的交集,而使用not时则输出父查询中与子查询的非交集。至于如何判断exists子查询属于独立还是父子关联查询,以及为什么父子关联exists子查询会对父查询构成筛选作用,解释起来需要很大的篇幅这里就不讲了。反正我们记住父子关联查询的最常用功能就是它可以求出两张表的交集或非交集(使用not关键字)和不使用group分组的情况下求出某张表的最大值或最小值。

现在回到题主的具体问题上,这个问题涉及到三张表,学生表student、选课表sc、课程表course。

提问要求列出选取了所有课程的学生名单。
下面是提问中给出的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));

从该语句我们看到它使用了两个嵌套父子关联不存在判断not exists子句,显然是要通过求非交集的方法查出选修了所有课程的学生名单。

一个学生如果他至少有一门课程没有选修,那么他在课程表里就会存在与选课表的非交集,我们姑且称之为“未选所有课程学生名单子集”,它由内层的not exists选出
...
select * from course
where not exists(
select * from sc
sno=student.sno
and cno=course.cno) ...

这个内层父子关联存在子查询选出课程表里与选课表的非交集,最内层选课表sc的课程号cno、学号sno分别与第二层父表course课程的cno、最外层父表studen学生表的sno进行对等连接,不存在对等的记录即为非交集,从而筛选出“未选所有课程学生名单子集”。

...未完待续追答

最终目的是检索出选修了所有课程的学生名单,我们从学生表里剔除掉“未选所有课程学生名单子集”,也就是学生表与该子集的非交集即为“选修了所有课程的学生名单”。这项任务由外层的不存在判断完成

select sname from students
where not exists(
未选所有课程学生名单子集);

请注意外层exists子句的父表student学号字段选课表sc学号的对等连接条件是在内层exists子句的where子句里进行交代的,这在sql语句里是被允许的,它使得嵌套父子关联查询语句的编写得以简化。

对于父子关联存在判断exists子查询,直接从字面上理解是很不明确的,但是如果改为从是否存在某一张表(父表)与另一张表(子表)的交集或非交集这个角度来理解,那么其逻辑就会变得比较清晰、易懂了。

顺便提一下,涉及父子关联exists子查询的sql语句常常给人高大上的感觉,但是请务必注意在碰到大数据表时,使用not关键字sql语句的运行效率问题,在有可被利用的索引的情况下not exists运行效率很高,可以放心使用,反之运行效率极低,应跟not in一样应避免使用!

参考技术A 一个用于检测子查询 一个在子查询中用于检测它的子查询追问

系统是怎么执行它的,,?

追答

先查询学生表数据,对于查询出来的每一个学生,再过检查没有选修的课程

java MySQL数据库编程 第四章 高级查询

第四章 高级查询(二)

(1)通过在子查询中使用EXISTS子句,可以对子查询中的行是否存在进行检查。子查询可以出现在表达式出现的如何位置

(2)子查询语句可以嵌套在SQL语句中任何表达式出现的位置。

一、EXISTS子查询

 

1.使用EXISTS语句判断该数据库对象是否存在:

DROP TABLE IF EXISTS temp;

 

2. EXISTS作为WHERE语句的子查询:

SELECT .....FROM 表名 WHERE EXISTS(子查询);

 

3. EXISTS关键字后面的参数是一个任意的子查询,如果该子查询有返回行。则EXISTS子查询的结果为true,此时再执行外层查询语句。如果子查询有没返回行。则EXISTS子查询的结果为false,此时不再执行外层查询语句。

二、NOT EXISTS子查询

EXISTS和IN一样,同样允许添加NOT关键字实现取返操作,NOT EXISTS表示不存在。

 

三、子查询注意事项

1)子查询可以嵌套在SQL语句中任何表达式出现的位置

         在SELECTE语句中,子查询可以被嵌套在SELECT语句的列、表和查询条件中,即SELECT子句、FROM子句、WHERE子句、GROUP BY子句和HAVING子句。

 

2)只出现在子查询中而没有出现在父查询中的的表不能包含在输出列中

         多层嵌套子查询的最终数据集只包含父查询的SELECT子句中出现的字段,而子查询的输出结果通常会作为其外层子查询数据源或用于数据判断匹配

以上是关于MySQL数据库代码中,两个exists语句同时出现同一查询语句中时,怎么理解,,越详细越好。,的主要内容,如果未能解决你的问题,请参考以下文章

MySql中in和exists效率

Mysql语句优化

MySQL Innodb表导致死锁日志情况分析与归纳

MySql中in和exists效率

关于MySQL 中 EXISTS 的用法

mysql的delete语句使用exists删除数据走不通