理解not exists()——执行过程
来源:互联网 发布:座机电话录音软件 编辑:程序博客网 时间:2024/06/06 16:36
在众多的SQL语句中,not exists()算是难以理解的一种了。
第一次看到,你会觉得有点迷糊,但是似乎还能够理解。但是当你看到下面这样一个例子的时候就会谷歌百度之了。
有这样的两个关系:
STUDENTS表即学生表,里面的属性sid表示学生编号,sname表示学生姓名。
CHOICES表即选课表,里面有sid,cid和tid三个属性。sid是学生编号,cid是该学生所选的课程编号,tid是讲该课程教师编号。
下面要求的是:查询选修了所有课程的学生姓名。
使用两次not exists()的答案是:
select sname from STUDENTS where not exists (select * from CHOICES as x where not exists (select * from CHOICES as y wherey.sid=STUDENTS.sid and y.cid=x.cid));
首先看内层,select * from CHOICES as x where not exists (select * fro CHOICES as y where y.cid=x.cid);这句话是意思是查询在选课记录中,没有学生S选修课程X的记录。也就是存在课程X,学生S没有选的记录,列出来。
然后是整句话的理解:不存在上述情况,即选课记录中不存在学生S没有选的课程。那就是列出选了全部课程的学生。
还是费解吧?程序员就应该用代码来理解真正的执行过程:
R = NIL; // 初始设置结果集合为空集open STUDENTS as C1; //准备扫描,设置游标C1while not EOF(C1) do //依次扫描C1begin fetch C1 into x; //取一行STUDENTS记录 R1 = NIL; //初始化临时结果集,用于存放STUDENTS记录 open CHOICES as C2; //准备扫描,设置游标C2 while not EOF(c2) do //依次扫描C2 begin fetch C2 into y; //取一行CHOICES记录 R2 = NIL; //初始化临时结果集,用于存放CHOICES记录 open CHOICES as C3; //准备扫描,设置游标C3 while not EOF(c3) do begin fetch C3 into z; if (z.sid == STUDENTS.sid and z.cid = y.cid) then begin //找到符合条件的记录 insert z into R2; //插入临时表 break; //对于(NOT) EXISTS, 找到一条即可 end; end; close C3; if R2 is NIL then //第3层没找到过符合条件的?(NOT EXISTS) begin insert y into R1; //插入临时表 break; //找到一条即可 end; end; close C2; if R1 is NIL then //第2层没找到过符合条件的?(NOT EXISTS) begin insert x into R; //插入最终结果集合 end;end;close C1;return R; //得到结果
注:这是我以前在一个网站上看到的,但是时间太长了,找不到出处了。
可以看到,这条SQL语句是从里层查找的,但每次要用外层的条件去匹配里层。只要找到一条符合条件的记录就退出。
如果你理解了就再来看一个例子吧:查询选修了教师号(tid)为1的教师 所开的所有课程的学生姓名。
由上述执行过程,我们应该把限定条件 tid=1 加在哪儿呢?如果是最内层,即
if (z.sid == STUDENTS.sid and z.cid = y.cid and z.tid='1' )
那么相应的SQL语句是:
select sname from STUDENTS where not exists (select * from CHOICES as x where not exists (select * from CHOICES as y where y.sid=STUDENTS.sid and y.cid=x.cid and y.tid=1));这是不正确的,因为:
假如某节课不是这个老师教的,最内层循环一定找不到,这样满足R2 is NIL,就会跳出来,去找下一个学生了。但是这门课本来就不是这个老师教的,根本不应该拿来匹配。
所以我们应该把限定条件加在外层,先确定这门课是这个老师教的,然后才进行匹配。select sname from STUDENTS where not exists (select * from CHOICES as x where x.tid=1 and not exists (select * from CHOICES as y where y.sid=STUDENTS.sid and y.cid=x.cid));
这是实验的两张表。因为实在传不了资源,就以图片的形式呈现了,有兴趣的可以自己创建。
CHOICES表
STUDENTS表
- 理解not exists()——执行过程
- IN/NOT IN---EXISTS/NOT EXISTS理解
- not in\in与not exists\exists—SQLCookbook
- 数据库NOT EXISTS的理解
- 开发随笔——NOT IN vs NOT EXISTS
- 数据库——SQL中in,not in,exists, not exists的区别
- SQL语句优化—in,not in,exists,not exists, left join...on
- sql not in 和 not exists (执行效率高)
- 《深入理解操作系统》1——程序的执行过程
- NOT EXISTS替代NOT IN EXISTS替换DISTINCT 识别‘低效执行’的SQL语句
- NOT EXISTS替代NOT IN EXISTS替换DISTINCT 识别‘低效执行’的SQL语句
- NOT EXISTS替代NOT IN 和 EXISTS替换DISTINCT 识别‘低效执行’的SQL语句
- 高级sql学习——exists和not exists的使用!!!
- 43.笔记 MySQL学习——EXISTS 和 NOT EXISTS子查询
- EXISTS 和 NOT EXISTS
- Exists/not exists 用法
- EXISTS 和 NOT EXISTS
- exists和not exists
- 14-斐波那契(算法)
- WinDbg调试器
- 1亿个整数求top 10000
- android上的一个网络接口和图片缓存框架enif简析
- JAVA学习之:类与类之间的关系
- 理解not exists()——执行过程
- Zend Framework 数据库(Db)操作总结
- 一套网络配置随时随地上网
- EAP协议和EAPoL协议
- Gesture Recognizers与触摸事件分发
- 高级Bash脚本编程指南(26):文本处理命令(二)
- python3.0与2.x之间的区别
- 15-水仙花数(算法)
- winfrom拷贝文件