您的位置:广东在线游戏网 > 游戏资讯 > 新手求助:最好简单明了点,sql中exist 和 not e...-SQL语句中exists和not exists的用法

新手求助:最好简单明了点,sql中exist 和 not e...-SQL语句中exists和not exists的用法

作者:广东在线游戏网日期:

返回目录:游戏资讯


in和exists
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。

如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)
效率e799bee5baa6e4b893e5b19e362低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的2:select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao');与
select name from student where name='zhang' or name='li' or
name='wang' or name='zhao'
的结果是相同的。

很简单,下面举个例子,例如:找出和张三一个班的所有学生,可以先查出张三所在班,然后再找所有和张三班相7a686964616fe78988e69d83363同的学生(使用 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)  -- 班级名和张三所在班级名相同

in 和 exists也是很好区别的.

in 是一个集合运算符.

a in {a,c,d,s,d....}

这个运算中,前面是一个元素,后面是一个集合,集合中的元素类型是和前面的元素一样的.

而exists是一个存在判断,如果后面的查询中有结果,则exists为真,否则为假.

in 运算用在语句中,它后面带的select 一定是选一个字段,而不是select *.

比如说你要判断某班是否存在一个名为"小明"的学生,你可以用in 运算:

"小明" in (select sname from student)

这样(select sname from student) 返回的是一个全班姓名的集合,in用于判断"小明"是否为此集合中的一个数据;

同时,你也可以用exists语句:

exists (select * from student where sname="小明")

exists : 强调的是是否返回结果e799bee5baa6e79fa5e98193e78988e69d83332集,不要求知道返回什么, 比如:
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))

相关阅读

关键词不能为空

标签导航

EVE欧服费用问题 关于EVE充值方法 EVE国际服如何充值 欧服EVE Online 现在免费了,收费和免费有什么区别?... 魔域中法师带什么BB最好? 魔域中各个职业带什么样的BB好啊 魔域里战士带什么BB最好? 魔域法师带什么bb好? 我要写玄幻小说,求一些奇花异草名称 求玄幻小说 不是洪荒的小说 有没有推荐的小说,要求:小说全文有很多的奇珍异兽,主人公有很... 里面有各种奇珍异兽 玄幻小说:魔兽 魔兽森林山脉、矿石、奇花异草、宝物、家族、技... 国土防线求怎样开启游戏 我下载的是游民星空的《国土防线》免安... 游民国土防线免安装中文汉化硬盘版下载 我下载完了 就给了一个... 我在游民星空下载了《国土防线》是免安装中文版的,下载玩后要解... 我在游民星空下载了一个国土防线免安装中文汉化硬盘版的,下载好... 新手求助:最好简单明了点,sql中exist 和 not e... sql中exists是什么意思,怎么讲解? 怎么用用sql语句中的not exists来写语句? Sql语句中IN和exists的区别及应用 魔域怎么幻化宠物 魔域主属幻化奥秘任务怎么做 魔域里的幻化衰衰草怎么得到的? 魔域中怎么把装备上的宝石取下来? 国际足联共有多少个成员国? 国际足联有多少个成员国 国际足联有多少成员国? 亚足联有多少个成员国? 《弹丸论破》游戏有两个结局吗? 弹丸论破2如何达成全员脱出结局 弹丸论破1里真的有全员逃脱结局吗?一共有多少结局? 弹丸论破的结局是什么,关于伪结局和全员脱出的结局又是什么呢,... qq坦克大战重坦克 哪个国家后期好用 qq坦克大战e50m怎么玩 德系50m玩法技巧分享 QQ游戏里面的坦克大战,里面那个速度很快且威力又大小坦克在哪... qq游戏中坦克大战打到八级怎么又从头开始打了 魔域BB神力等级有什么用!? 魔域里BB的神力等级有什么用? 魔域BB神力等级高低有什么好处? 魔域里的BB的神阶有什么用啊? 下列被誉为“活化石”的是国家一级保护动物是(  )A.蒙古野... 青藏高原特有的国家一级保护动物是(  )A.大熊猫B.沙燕C... 我国被誉为“活化石”的国家一级保护动物动物是(  )A.丹顶... 下列动物属于国家一级保护动物的是(  )A.丹顶鹤 朱鹮 ... dnf加暴击的宝珠有哪些 dnf物理暴击宝珠有哪些的 dnf物理暴击宝珠有哪些? dnf头肩加物理暴击的宝珠叫什么名 以“我们的思想”为主题,设计一个主题班会活动方案 苏式战机为什么后面有个尾巴呢