首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你真的会玩SQL吗?EXISTS和IN之间的区别

你真的会玩SQL吗?EXISTS和IN之间的区别

作者头像
欢醉
发布2018-01-22 18:24:56
7790
发布2018-01-22 18:24:56
举报
文章被收录于专栏:james大数据架构james大数据架构

你真的会玩SQL吗?系列目录

你真的会玩SQL吗?之逻辑查询处理阶段

你真的会玩SQL吗?和平大使 内连接、外连接

你真的会玩SQL吗?三范式、数据完整性

你真的会玩SQL吗?查询指定节点及其所有父节点的方法

你真的会玩SQL吗?让人晕头转向的三值逻辑

你真的会玩SQL吗?EXISTS和IN之间的区别

你真的会玩SQL吗?无处不在的子查询

你真的会玩SQL吗?Case也疯狂

你真的会玩SQL吗?表表达式,排名函数

你真的会玩SQL吗?简单的 数据修改

你真的会玩SQL吗?你所不知道的 数据聚合

你真的会玩SQL吗?透视转换的艺术

你真的会玩SQL吗?冷落的Top和Apply

你真的会玩SQL吗?实用函数方法汇总

你真的会玩SQL吗?玩爆你的数据报表之存储过程编写(上)

你真的会玩SQL吗?玩爆你的数据报表之存储过程编写(下)

此文是继文章 你真的会玩SQL吗?三值逻辑 而补充的,那来探讨下为什么有人会建议有些地方用EXISTS代替in

EXISTS和IN之间的区别

1.EXISTS只返回TRUE或FALSE,不会返回UNKNOWN。

2.IN当遇到包含NULL的情况,那么就会返回UNKNOWN。

当查询的列包含NULL时,NOT EXISTS正常返回TRUE或FALSE。

而NOT IN可能返回空集,如下

1:val IN(val1,val2,...,NULL),永远不会返回FALSE,而是返回TRUE或UNKNOWN。

2:val NOT IN(val1,val2,...,NULL),永远不会返回TRUE,而是返回NOT TRUE或NOT UNKNOWN。

看个示例:

Test1表

select t.[name] from Test as t

where  exists (select t1.orderid from Test1 as t1 where t1.[name]=t.[name])

返回 aaa,ccc,ddd

select t.[name] from Test as t

where  t.[name] in  (select t1.[] from Test1 as t1)

返回 aaa,ccc,ddd

select t.[name] from Test as t

where  not exists (select t1.orderid from Test1 as t1 where t1.[name]=t.[name])

返回 bbb

select t.[name] from Test as t

where  t.[name] not in  (select t1.[name] from Test1 as t1)

返回空集

练习

以下对就返回哪三值?

答案

用例数据库文件 你真的会玩SQL吗?之逻辑查询处理阶段 文末

/*写一条查询语句,返回在2007年下过订单,而在2008年没有下过订单的客户。
涉及的表:Sales.Customers表和Sales.Orders表。用exists
期望的输出:*/
custid      companyname
----------- ----------------------------------------
21          Customer KIDPX
23          Customer WVFAF
33          Customer FVXPQ
36          Customer LVJSO
43          Customer UISOJ
51          Customer PVDZC
85          Customer ENQZT

参考SQL:

--answer:
select custid, companyname
from Sales.Customers as C
where EXISTS
  (select *
   from Sales.Orders as O
   where O.custid = C.custid
     and O.orderdate >= '20070101'
     and O.orderdate < '20080101')
  and not EXISTS
  (select *
   from Sales.Orders as O
   where O.custid = C.custid
     and O.orderdate >= '20080101'
     and O.orderdate < '20090101');
/*
1.先处理外层查询,从Sales.Customers表别名C中取出一个元组,将元组相关列值custid传给内层查询
2.执行第一层内层查询,Sales.Orders表别名O,应用where子句返回满足条件O.custid = C.custid和orderdate在2007年至2008年
3.执行第二层内层查询,Sales.Orders表别名O应用where子句返回满足条件O.custid = C.custid和orderdate在2008年至2009年的值
4.执行not EXISTS,外查询根据子查询返回的结果集得到满足条件的行
*/
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-11-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云 BI
腾讯云 BI(Business Intelligence,BI)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,帮助经营者快速获取决策数据依据。系统采用敏捷自助式设计,使用者仅需通过简单拖拽即可完成原本复杂的报表开发过程,并支持报表的分享、推送等企业协作场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档