EXISTS与NOT EXISTS
- EXISTS:表示存在xxx。在查询的外层添加一个EXISTS,当内层查询有结果,则该EXISTS返回true,反之返回false
- NOT EXISTS:表示不存在xxx。在查询的外层添加一个NOT EXISTS,当内层查询有结果,则该NOT EXISTS返回false,反之返回true
表生成的过程
SELECT Sname
FROM Student
WHERE NOT EXISTS(1)
(SELECT *
FROM Course
WHERE NOT EXISTS(2)
(SELECT *
FROM SC
WHERE Sno= Student.Sno
AND Cno= Course.Cno));
学生表
课程表
学生选课表
以上面的为例:首先改例子中有两个EXISTS,我们先从最里面的内容开始,当一个元组和课程表中的第一个元组在最里层循环中与SC.sno和SC.cno进行匹配的时候。
(情况1)若配上最内层的WHERE将该数据插入到临时表中,第一个NOT EXISTS(指内层的NOT EXISTS,代码中的(2))判断该临时表不为空则返回false。
(情况2)若没有匹配上最内层的WHERE返回false,则不将数据插入到临时的表中,第一个NOT EXISTS(是内层的NOT EXISTS,代码中的(2))判断结果表为空返回true
当Course循环结束之后
第二个NOT EXISTS(最外层的NOT EXISTS,代码上的(1))判断该内层返回集是否为空。
(1)若为内层的NOT EXISTS返回true,WHERE接收到true之后将数据插入临时的结果集中,第二个NOT EXISTS判断临时表不为空,则返回false,不将内容添加到最终的结果集中。
(2)若为内层的NOT EXISTS返回false,WHERE接收到false之后不将数据插入到临时的结果集中,第二个NOT EXISTS判断临时表为空,则返回true,将内容添加到最终的结果集中。
本人的语言表达能力不足,要是上面的内容没有看明白的话,一下是我总结的方法:
WHERE语句是当判断的结果为true的时候,将内容添加到结果集中,若为false的话,则不讲内容添加到结果集中。
EXISTS是当查询的表为非空的时候则返回true,当查询的表为空的时候返回false。
NOT EXISTS则是当查询的表为空的时候返回true,当查询的表为非空的时候返回false。
//查询选择了全部课程的学生的查询语句
SELECT Sno
FROM Student s
WHERE NOT EXIXTS(
SELECT *
FROM Course c
WHERE NOT EXISTS(
SELECT *
FROM SC sc
WHERE sc.sno = s.sno
AND sc.cno = c.cno
)
);
个人的理解:其中外层的Student与次外层的Course的组合分别与SC中的内容进程比较,将符合要求的内容进行保留
若没有听明白的话可以通过上面的方法进行推到来得出自己的观点