数据库NOT EXISTS的理解
2016-04-08 17:39
260 查看
数据库有查询有四种运算:选择、投影、连接、除运算;而NOT EXISTS关键字则是基于除运算的查询。
例如:
SC表(Sno是学生号,Cno是课程号)
Student表
Course表
一. 查询选修了全部课程的学生的姓名。
此时,查询涉及到三个表。查询方式如下:
可以将这个句子看成两部分,所以:
最外层查询:
没有 就是代表不存在,也就是说,对于Student,就是为了寻找符合
<没有> 这个条件的Sname;好的,这个语句的一部分工作完成了,接下来写子语句的时候就不再考虑
<没有> 条件。
第一层子查询:
现在开始考虑 <一门课程他没选的> , 也就是说,现在的工作是:子查询试图努力找出一门他没选的课程;即是,对于某个Cno ,不存在 .... (然后开始第二层子查询)。
第二层子查询:
这个时候,又是对第一层查询的否定了,这时候意思是:
对于从第二层查询迭代来的Cno , 看有没有与内层Cno相等的;且,Sno=Student.Sno。
Sno=Student.Sno作用:
图.1 Sno=Student.Sno作用
二.查询至少选修了学生201215122选修的全部课程的学生号码。
此时,查询只涉及SC表。
即是:对于符合条件的y,不存在一门课程,201215122选了,而y学生没有选。
此处的s1.Sno=s3.Sno 的作用和图.1一样。
例如:
SC表(Sno是学生号,Cno是课程号)
+-----------+-----+-------+ | Sno | Cno | Grade | +-----------+-----+-------+ | 201215121 | 1 | 92 | | 201215121 | 2 | 85 | | 201215121 | 3 | 88 | | 201215122 | 2 | 90 | | 201215122 | 3 | 80 | +-----------+-----+-------+
Student表
+-----------+--------+------+------+-------+ | Sno | Sname | Ssex | Sage | Sdept | +-----------+--------+------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | | 201215122 | 刘晨 | 女 | 19 | CS | | 201215123 | 王敏 | 女 | 18 | MA | | 201215125 | 张立 | 男 | 19 | IS | +-----------+--------+------+------+-------+
Course表
+-----+--------------+------+---------+ | Cno | Cname | Cpno | Ccredit | +-----+--------------+------+---------+ | 1 | 数据库 | 5 | 4 | | 2 | 数学 | NULL | 2 | | 3 | 信息系统 | 1 | 4 | | 4 | 操作系统 | 6 | 3 | | 5 | 数据结构 | 7 | 4 | | 6 | 数据处理 | NULL | 2 | | 7 | PASCAL语言 | 6 | 4 | +-----+--------------+------+---------+
一. 查询选修了全部课程的学生的姓名。
此时,查询涉及到三个表。查询方式如下:
select Sname from Student where not exists // (1)没有一门课程他没选的 (对于某个Sname) ( select * from Course where not exists // (2)一门课程他没选的。(对于某个Cno) ( select * from SC where Sno=Student.Sno and Cno=Course.Cno ) );因为,题目的意思也就是:没有一门课程他没有选的。
可以将这个句子看成两部分,所以:
最外层查询:
没有 就是代表不存在,也就是说,对于Student,就是为了寻找符合
<没有> 这个条件的Sname;好的,这个语句的一部分工作完成了,接下来写子语句的时候就不再考虑
<没有> 条件。
第一层子查询:
现在开始考虑 <一门课程他没选的> , 也就是说,现在的工作是:子查询试图努力找出一门他没选的课程;即是,对于某个Cno ,不存在 .... (然后开始第二层子查询)。
第二层子查询:
这个时候,又是对第一层查询的否定了,这时候意思是:
对于从第二层查询迭代来的Cno , 看有没有与内层Cno相等的;且,Sno=Student.Sno。
Sno=Student.Sno作用:
图.1 Sno=Student.Sno作用
二.查询至少选修了学生201215122选修的全部课程的学生号码。
此时,查询只涉及SC表。
即是:对于符合条件的y,不存在一门课程,201215122选了,而y学生没有选。
select DISTINCT Sno from SC s1 where not exists // 不存在 ( select * from SC s2 where s2.Sno='201215122' and not exists // 201215122选了,y学生没有选(对于被20121522选了的Cno) ( select * from SC s3 where s1.Sno=s3.Sno and s3.Cno=s2.Cno ) );
此处的s1.Sno=s3.Sno 的作用和图.1一样。
相关文章推荐
- MySQL的btree索引和hash索引的区别
- 事务四大特性详解
- MongoDB学习 (六):查询
- kettle中使用mysql的tinyint 类型到slqserver的tinyint类型
- NopCommerce架构分析之三---数据库初试化及数据操作
- SpringMVC+ibatis+MySQL+MongoDB构建博客系统(一)
- oracle函数listagg的使用说明
- 从数据库(wm_concat函数)接收值变成oracle.sql.CLOB@xxxxx类型的处理方法
- MySql中的时间类型datetime,timestamp,date,year比较
- Mysql中的存储过程详解
- windows系统如何安装mysql-5.7.9-win32
- Mysql 的一些异常解决
- 表单内容插入数据库
- mssqlserver 链接 mysql
- mysql删除数据库表中重复数据(根据单个或多个字段)
- Sqlserver 安装
- mysql数据库备份和恢复
- PHP用redis实现多进程队列
- Redis-cli命令最新总结
- mysql在线DDL(与oracle的区别)