关于notexists的信息
SQL语句中exists和not exists的用法,讲得通俗易懂些。
exists : 强调的是是否返回结果集,不要求知道返回什么, 比如:
select name from student where sex = 'm' and mark exists(select 1 from grade where ...) ,只要
exists引导的子句有结果集返回,那么exists这个条件就算成立了,大家注意返回的字段始终为1,如果改成“select 2 from grade where ...”,那么返回的字段就是2,这个数字没有意义。所以exists子句不在乎返回什么,而是在乎是不是有结果集返回。
而 exists 与 in 最大的区别在于 in引导的子句只能返回一个字段,比如:
select name from student where sex = 'm' and mark in (select 1,2,3 from grade where ...)
,in子句返回了三个字段,这是不正确的,exists子句是允许的,但in只允许有一个字段返回,在1,2,3中随便去了两个字段即可。
而not exists 和not in 分别是exists 和 in 的 对立面。
exists (sql 返回结果集为真)
not exists (sql 不返回结果集为真)
下面详细描述not exists的过程:
如下:
表A
ID NAME
1 A1
2 A2
3 A3
表B
ID AID NAME
1 1 B1
2 2 B2
3 2 B3
表A和表B是1对多的关系 A.ID = B.AID
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE A.ID=B.AID)
执行结果为
1 A1
2 A2
原因可以按照如下分析
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1)
---SELECT * FROM B WHERE B.AID=1有值返回真所以有数据
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2)
---SELECT * FROM B WHERE B.AID=2有值返回真所以有数据
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3)
---SELECT * FROM B WHERE B.AID=3无值返回真所以没有数据
NOT EXISTS 就是反过来
SELECT ID,NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID=B.AID)
执行结果为
3 A3
===========================================================================
EXISTS = IN,意思相同不过语法上有点点区别,好像使用IN效率要差点,应该是不会执行索引的原因
SELECT ID,NAME FROM A WHERE ID IN (SELECT AID FROM B)
NOT EXISTS = NOT IN ,意思相同不过语法上有点点区别
SELECT ID,NAME FROM A WHERE ID NOT IN (SELECT AID FROM B)
有时候我们会遇到要选出某一列不重复,某一列作为选择条件,其他列正常输出的情况.
如下面的表table:
Id Name Class Count Date
1 苹果 水果 10 2011-7-1
1 桔子 水果 20 2011-7-2
1 香蕉 水果 15 2011-7-3
2 白菜 蔬菜 12 2011-7-1
2 青菜 蔬菜 19 2011-7-2
如果想要得到下面的结果:(Id唯一,Date选最近的一次)
1 香蕉 水果 15 2011-7-3
2 青菜 蔬菜 19 2011-7-2
正确的SQL语句是:
SELECT Id, Name, Class, Count, Date
FROM table t
WHERE (NOT EXISTS
(SELECT Id, Name, Class, Count, Date FROM table
WHERE Id = t.Id AND Date t.Date))
如果用distinct,得不到这个结果, 因为distinct是作用与所有列的
SELECT DISTINCT Id, Name, Class, Count, Date FROM table
结果是表table的所有不同列都显示出来,如下所示:
1 苹果 水果 10 2011-7-1
1 桔子 水果 20 2011-7-2
1 香蕉 水果 15 2011-7-3
2 白菜 蔬菜 12 2011-7-1
2 青菜 蔬菜 19 2011-7-2
如果用Group by也得不到需要的结果,因为Group by 要和聚合函数共同使用,所以对于Name,Class和Count列要么使用Group by,要么使用聚合函数. 如果写成
SELECT Id, Name, Class, Count, MAX(Date)
FROM table
GROUP BY Id, Name, Class, Count
得到的结果是
1 苹果 水果 10 2011-7-1
1 桔子 水果 20 2011-7-2
1 香蕉 水果 15 2011-7-3
2 白菜 蔬菜 12 2011-7-1
2 青菜 蔬菜 19 2011-7-2
如果写成
SELECT Id, MAX(Name), MAX(Class), MAX(Count), MAX(Date)
FROM table
GROUP BY Id
得到的结果是:
1 香蕉 水果 20 2011-7-3
2 青菜 蔬菜 19 2011-7-2
如果用in有时候也得不到结果,(有的时候可以得到,如果Date都不相同(没有重复数据),或者是下面得到的Max(Date)只有一个值)
SELECT DISTINCT Id, Name, Class, Count, Date FROM table
WHERE (Date IN
(SELECT MAX(Date)
FROM table
GROUP BY Id))
得到的结果是:(因为MAX(Date)有两个值2011-7-2,2011-7-3)
1 桔子 水果 20 2011-7-2
1 香蕉 水果 15 2011-7-3
2 青菜 蔬菜 19 2011-7-2
注意in只允许有一个字段返回
有一种方法可以实现:
SELECT Id, Name, Class, COUNT, Date
FROM table1 t
WHERE (Date =
(SELECT MAX(Date)
FROM table1
WHERE Id = t .Id))
oracle中not exists 是什么意思
not exists就是检测有没有符合条件的记录的意思。
一般放到where后面,检测子查询的结果。
NOT EXISTS 的用法
就是不存在的条件,譬如
SELECT * FROM TABLE where not exists (select 1 from table a)
括号里面的肯定存在,那么这条语句select的结果就没有任何数据
怎么理解数据库中not exist?
not exists 是取反逻辑,也就是里面查询没有结果集就是为真,如果有结果集就是为假。然后作为整体的条件拼接到著查询上
NOT EXISTS 怎么用?
exists not exists 详细解释
exists 只有满足条件(存在的条件)才返回(输出对应值,再取下一个条件值进行遍历),
当全部遍历没有满足条件的话也返回(返回”不满足满足exists“的意思,要求外循环取下一个值遍历)。
not exists 只有满足条件(不存在的条件)才返回(输出对应值,再取下一个条件值进行遍历),
当全部遍历没有满足条件(不存在的条件)的话也返回(返回”不满足满足 not exists“的意思,要求外循环取下一个值遍历)。
1 2 3 取1中一个值 ——取2中一个值当满足3就返回,输出对应条件1的最外层SQL——取2中一个值当不满足,继续取2中下一个值,如果这时候有满足的也返回
输出相应的1这个值为条件的信息,但是当都不满足的话 返回假判断第1层的where,要是where中是假的话就假假为真了,为真就输出相应的信息。
接着取1的下一个值 ,再取2中的一个值 ......重复这些过程。
一: 只要选了课的输出即输出选了课的信息
select *
from xs a
where exists
(select *
from kc b
where exists
(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch)
);
a 取 990201 b 取 101 当存在exists (select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) ); 则
(select *
from kc b
where exists 就也存在 。输出990201的信息。 990202......
a 取 990203 b 取 101 不存在101使exists (select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );为真
紧接着就在b中取下一个即202进行判断,202可以使exists (select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );为真
(select *
from kc b
where exists 就也存在 。输出990203的信息。
a 取990301 b取101 不可以使exists (select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );为真
紧接着就在b中取下一个即202进行判断,也不可以使exists (select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );为真
b取203 也一样不可以,没有找到满足情况的则返回最外循环 , a 取990302 .....
二: 作用:输出只要有一门课没有选修的学生信息。
select *
from xs a
where exists
(select *
from kc b
where not exists
(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch)
);
a 取一个学号值 , b 取一个课程号值 假如a 对应的b满足not exists(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );
即a没有选对应b课程。(select *
from kc b
where not exists
(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) 为真 ,第1层又是exists 所以把没有选课程a的一学号值的信息输出,
反之当b取一个课程号值 ,假如a 对应的b不满足 not exists(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );
即a选了对应b课程。(select *
from kc b
where not exists
(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) 为假 ,则继续取b的下一个值,假如一直没找到满足 not exists的则,返回最外层,
然后a取下一个值,.....这样重复直到a遍历完。 这里就是当你a中选一个学号值, 对应b中只要存在没有选课的情况就输出。否则取下a的下一个值遍历。
三: 作用:一门课程也没有选修的学生信息
select *
from xs a
where not exists
(select *
from kc b
where exists --不满足条件的放过 只有满足条件的才返回真,当都没满足则取下一个a再遍历。
(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch)
);
a 取一个学号值 , b 取一个课程号值 假如a 对应的b满足 exists(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );
即a选了对应b课程。(select *
from kc b
where not exists
(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) 为真 ,但是第1层是 not exists 所以选了课程a的一学号值的信息不会输出,
反之当b取一个课程号值 ,假如a 对应的b不满足 exists(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );
即a没有选对应b课程。(select *
from kc b
where not exists
(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) 为假 ,则继续取b的下一个值,假如遍历完b一直没找到满足exists的则第1层的not exists为真,
返回最外层,输出对应的信息。然后a取下一个值,.....这样重复直到a遍历完。 这里就是当你a中选一个学号值, 当你存在一个选课程使第2层exists为真 ,
但是第1层 not exists就为假了(即一个a只要选了课程就不会输出),对应b中只有都没有选课的情况就输出(因为当全部遍历完b的时候都没有则返回假,
第1层有not exists所以为真就输出)。这里关键的是对于不满足情况怎么处理:相关子查询中当你碰到可以取真的则返回输出相应条件对应的查询值,当你都取的是假
对于单层exists或not exists则取下一个值遍历,对于多层则返回假再去判断倒数第2层的情况。
四: 作用:输出没有一门课程没有选修的学生信息。
select *
from xs
where not exists
(select *
from kc
where not exists
(select * from xs_kc where xh=xs.xh and kch=kc.kch)
);
a 取一个值 ,b 中取一个值 ,假如a 对应的b满足 not exists(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );
即a没有选了对应b课程。(select *
from kc b
where not exists
(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) 为真 ,但是第1层是 not exists 所以没有选课程a的一学号值的信息不会输出,
反之当b取一个课程号值 ,假如a 对应的b不满足 not exists(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) );
即a选了对应b课程。(select *
from kc b
where not exists
(select * from xs_kc c where c.xh=a.xh and c.kch=b.kch) 为假 ,则继续取b的下一个值,假如遍历完b一直没找到满足 not exists的则第1层的not exists为真,
返回最外层,输出对应的信息。然后a取下一个值,.....这样重复直到a遍历完。 这里就是当你a中选一个学号 当b有一个对应值的满足第2层not exists(即没有选课)
就不会输出信息,当b中有一个对应值的不满足第2层not exists(即选了课)(不满足不会处理,直接取下一个,只有全部取完当没有才返回假),则继续遍历下一个b,
当遍历完b没有满足not exists的(即选全了b中的课程的),返回假,而第1层为 not exists 所有为真,输出这个选择了所有b课程的学号的信息。
spark中notexists条件写法
Spark中notexists条件的写法为:NOT EXISTS(子查询)。子查询是另一个查询语句,它可以是单行查询也可以是多行查询。如:SELECT 列名 FROM 表名 WHERE NOT EXISTS (SELECT 列名 FROM 另一个表名)。