SQL NOT EXISTS讲解 (详例助理解)
Posted 风去幽墨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL NOT EXISTS讲解 (详例助理解)相关的知识,希望对你有一定的参考价值。
首先我们要知道对于exists和not exists 的返回值都是真假。
exists :如果子查询查询到了列那么就为假
not exists : 如果子查询查询不到结果则返回值为真
下面来举例子来理解not exists:
先给出三个表:
student:
sno(学号) |
---|
s1 |
s2 |
course:
cno(课程号) |
---|
c1 |
c2 |
sc(选课系统):
sno(学号) | cno(课程号) |
---|---|
s1 | c1 |
s1 | c2 |
s2 | c1 |
现在我们希望能够查询到选修了所有课程的学生学号:
--SQL查询
SELECT sno --xz1
FROM student s
WHERE NOT EXISTS(SELECT * --bcz1 xz2
FROM course c
WHERE NOT EXISTS(SELECT * --bcz2 xz3
FROM sc
WHERE sc.sno=s.sno AND sc.cno=c.cno));
下面来解释一下查询过程:
我们先按顺序记录一下选择 xz1,xz2,xz3
不存在 bcz1,bcz2.(拼音首字母)
我们可以将其选择过程看作是一个循环嵌套(第一层为student,第二层为course ,第三层为sc)
对于xz1 我们查询的对象是student
其下有两个成员 s1,s2
//现在查询s1
对应的bcz1的子查询的对象是course
其下有俩成员c1,c2
//现在查询s1-c1
对于bcz2的子查询的对象是sc
其下有三个成员: s1-c1 s1-c2 s2-c1
里面有s1-c1 所以xz3可以查询到一条结果
bcz2能接收到一条结果所以此时为假
xz2因为bcz2为假此时查询不到结果
此时bcz1也还没有接收到结果所以为真
*****************************
//现在查询s1-c2
对于bcz2的子查询的对象是sc
其下有三个成员: s1-c1 s1-c2 s2-c1
里面有s1-c2 所以xz3可以查询到一条结果
bcz2能接收到一条结果所以此时为假
xz2因为bcz2为假此时查询不到结果
此时bcz1也还没有接收到结果所以为真
对于s1的查询完毕:bcz2接收到了两条结果所以两次为假, 因而xz2 一条信息都没有查询到, 因而bcz1 一条结果都没接收到所以bcz1结果为真,xz1此时查询到了s1.
**************************************************************************************************
//现在查询s2
对应的bcz1的子查询的对象是course
其下有俩成员c1,c2
//现在查询s2-c1
对于bcz2的子查询的对象是sc
其下有三个成员: s1-c1 s1-c2 s2-c1
里面有s2-c1 所以xz3可以查询到一条结果
bcz2能接收到一条结果所以此时为假
xz2因为bcz2为假此时查询不到结果
此时bcz1也还没有接收到结果所以为真
*******************************
//现在查询s2-c2
对于bcz2的子查询的对象是sc
其下有三个成员: s1-c1 s1-c2 s2-c1
里面没有s2-c2 所以xz3查询不到结果
bcz2没有接收到一条结果所以此时为真
xz2因为bcz2为真此时查询到一条结果
此时bcz1接收到xz2结果所以为假
对于s2的查询完毕:bcz2接收到了一条结果所以两次分别为假和真, 因而xz2 可以在bcz2为真时查询道一条信息, 因而bcz1 接收了一条结果所以bcz1结果为假,xz1此时查询不到了s2.
所以最终结果为 s1
也可以从理解上下手:
既然要查询选修了所有课程的学生。那么只要出现了少选一门课程的学生就不是我们要找的对象。
可以用不存在来筛选,只要有一门课他没选,我就不选他。这里就是两个not exists 的含义。
只要我在sc查不到你这个关系,最内层的选择就没有返回值,那么中层的选择就能查到结果,那么最外层的not exists 就为假,最外层的选择就选不到这个学生。
还是多理解理解吧!
若有错误,欢迎指出和评论!
以上是关于SQL NOT EXISTS讲解 (详例助理解)的主要内容,如果未能解决你的问题,请参考以下文章