zoukankan      html  css  js  c++  java
  • 你真的会玩SQL吗?EXISTS和IN之间的区别

    此文是继文章 你真的会玩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,外查询根据子查询返回的结果集得到满足条件的行
    */
    复制代码
  • 相关阅读:
    标题
    Ubuntu配置 PPTP 服务器端
    网络虚拟化问题小记
    DevStack部署Openstack环境
    Ubuntu LVM扩展LV
    Gnocchi+Aodh服务简析
    部署Ceilometer +Gnocchi + Aodh
    Runing MAC on KVM 问题小记
    处理 Ceilometer UPD 丢包
    TC limit bandwidth
  • 原文地址:https://www.cnblogs.com/8080zl/p/8603106.html
Copyright © 2011-2022 走看看