问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

新手求助:最好简单明了点,sql中exist 和 not exist 的区分如何理解他们??

发布网友 发布时间:2022-09-18 17:20

我来回答

4个回答

热心网友 时间:2023-10-22 17:35

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))

比如在Northwind数据库中有一个查询为
SELECT c.CustomerId,CompanyName FROM Customers c
WHERE EXISTS(
SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID)
这里面的EXISTS是如何运作呢?子查询返回的是OrderId字段,可是外面的查询要找的是CustomerID和CompanyName字段,这两个字段肯定不在OrderID里面啊,这是如何匹配的呢?

EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
EXISTS 指定一个子查询,检测 行 的存在。

语法: EXISTS subquery
参数: subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。
结果类型: Boolean 如果子查询包含行,则返回 TRUE ,否则返回 FLASE 。

例表A:TableIn 例表B:TableEx

(一). 在子查询中使用 NULL 仍然返回结果集
select * from TableIn where exists(select null)
等同于: select * from TableIn

(二). 比较使用 EXISTS 和 IN 的查询。注意两个查询返回相同的结果。
select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)
select * from TableIn where ANAME in(select BNAME from TableEx)

(三). 比较使用 EXISTS 和 = ANY 的查询。注意两个查询返回相同的结果。
select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)
select * from TableIn where ANAME=ANY(select BNAME from TableEx)

NOT EXISTS 的作用与 EXISTS 正好相反。如果子查询没有返回行,则满足了 NOT EXISTS 中的 WHERE 子句。

结论:
EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。 EXISTS内部有一个子查询语句(SELECT ... FROM...), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。

一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。

分析器会先看语句的第一个词,当它发现第一个词是SELECT关键字的时候,它会跳到FROM关键字,然后通过FROM关键字找到表名并把表装入内存。接着是找WHERE关键字,如果找不到则返回到SELECT找字段解析,如果找到WHERE,则分析其中的条件,完成后再回到SELECT分析字段。最后形成一张我们要的虚表。
WHERE关键字后面的是条件表达式。条件表达式计算完成后,会有一个返回值,即非0或0,非0即为真(true),0即为假(false)。同理WHERE后面的条件也有一个返回值,真或假,来确定接下来执不执行SELECT。
分析器先找到关键字SELECT,然后跳到FROM关键字将STUDENT表导入内存,并通过指针找到第一条记录,接着找到WHERE关键字计算它的条件表达式,如果为真那么把这条记录装到一个虚表当中,指针再指向下一条记录。如果为假那么指针直接指向下一条记录,而不进行其它操作。一直检索完整个表,并把检索出来的虚拟表返回给用户。EXISTS是条件表达式的一部分,它也有一个返回值(true或false)。

在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,可以通过使用 EXISTS 条件句防止插入重复记录。
INSERT INTO TableIn (ANAME,ASEX)
SELECT top 1 '张三', '男' FROM TableIn
WHERE not exists (select * from TableIn where TableIn.AID = 7)

EXISTS与IN的使用效率的问题,通常情况下采用exists要比in效率高,因为IN不走索引,但要看实际情况具体使用:
IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

热心网友 时间:2023-10-22 17:35

很简单,下面举个例子,例如:找出和张三一个班的所有学生,可以先查出张三所在班,然后再找所有和张三班相同的学生(使用 exists),如

select a.*
  from students a
 where exists(
          select 1  -- 只要有记录就说明和张三一个班
            from students b
           where stuname = '张三'   -- 姓名为张三
             and a.classname = b.classname)  -- 班级名和张三所在班级名相同

找出所有和张三不在一班的学生(使用not exists)

select a.*
  from students a
 where not exists(
          select 1  -- 只要有记录就说明和张三一个班
            from students b
           where stuname = '张三' -- 姓名为张三
             and a.classname = b.classname)  -- 班级名和张三所在班级名相同

追问exists 和not exists 强调返回的是结果集 ture or false 那exists(
*******)这个结果是 返回的是个ture的那结果集 前面的这个查询如何理解..????

追答select a.*
  from students a
-- 上面这个就是一个普通的查询,查询 student 表中的所有记录,使用下面的条件
 where exists  -- 由这个限定查询的结果,表示某结果集存在
               -- 下面是子查询
   select 1 from student b   -- 还是从 student 表中查询
    where b.stuname = '张三' -- 找姓名为“张三”的记录,此时已经定位到张三了
      and a.classname = b.classname  -- 找到和张三一个班级的记录,此时 b.classname 为张三所在的班级名,a.classname = b.classname 也就是上面的 [from student a] 表中的字段 classname 等于张三所在班级名的记录,此时所有 classname = [张三所在班级名] 的记录都被返回

热心网友 时间:2023-10-22 17:36

exist 是存在的意思
not exist 就是不存在

例如: if exists(select * from tablea where a=1) 如果括弧中的语句存在结果集那麼就执行下面的begin end 中的语句
begin

end

热心网友 时间:2023-10-22 17:36

exists : 强调的是是否返回结果集,不要求知道返回什么, 比如:
select
name
from student
where sex = 'm'
and exists(select 1 from grade where grade_id = 1) ,只要
exists引导的子句有结果集返回,那么exists这个条件就算成立了,大家注意返回的字段始终为1,如果改成“select 2 from grade where ...”,那么返回的字段就是2,这个数字没有意义。所以exists子句不在乎返回什么,而是在乎是不是有结果集返回。

not exists 相反
exists (sql 返回结果集为真)
not exists (sql 不返回结果集为真)
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
邪灯是什么意思? 趣头条怎么解绑微信 趣头条APP解绑微信教程 趣头条怎么解绑微信号 趣头条怎样解除微信绑定 魔兽世界7.0古龙之陨怎么做 咸阳男子欲带孩子轻生被救回,成年人的生活有多不易? 陕西咸阳,一男子欲带孩子轻生被救回,轻生带孩子是什么操作? 我是帅哥,为什么还没有人追? 为什么我这么漂亮就是没有一个男人来追我 气死了? 人不在本地,怎么实名制 宜昌市维也纳酒店(凤山店)在哪 ? 孩子听不进去伴随着言语抗拒、肢体反抗等,家长应要如何应对? 第三代社保卡需要更换吗?有什么用? 第三代社保卡有什么新功能 第三代社保卡和第二代社保卡的区别 单油饼怎么做 电离和水解过程都是吸热的吗 电离,水解分别是吸热还是放热 高中生的入党申请书范文 中和反应,电离,水解,是放热还是吸热反应? 我想在淘宝卖一个cf号,要准备什么?具体流程怎么弄? 电离和水解分别是吸热还是放热? 水解和电离哪个是放热哪个是吸热?为什么?请快速解答!!谢谢 电离和水解都是吸热反应吗 请问一下无痕钉怎么完整取下来 请问无痕钉怎么完整取下来 Nancy的含义和意思 为什么电离反应和水解都是吸热反因呢,一直认为水解和电离是相反的说 电离或水解时为什么吸热? 为什么水解和电离都需要吸热 女人说37度7指的是什么 维也纳位于哪的南部 英语阅读训练八年级下三单元1,2篇翻译 八年级新目标下册英语13页翻译和14页翻译 初中英语阅读训练八下第4单元第20页passagec翻译 请问怎么弄成pdf格式 五到六岁儿童教育方法 对付白羊男绝对要冷 幼儿教育哪里好 56岁儿童教育 家长对小孩的教育 怎样让白羊男主动表白 节假日银行可以打征信吗 银行节假日可以打征信吗 35钢化学成分 运城周边漂流哪里好玩 茶卡盐湖有住的地方吗? 请问一下去茶卡盐湖要准备什么 请问去茶卡盐湖要准备什么 龙是否真实存在过?盘点三大实物证据,考古学家:铁证如山! 干拌江西米粉的家常做法怎么做好吃 为什么要使用石材防护剂了?有什么意义呀? 南昌米粉的家常做法大全怎么做好吃视频 石材防护剂是什么? 石材为什么防护?石材防护剂是什么?