IN VS EXIST子查询

时间:2016-08-13 01:54:07

标签: sql sql-server

为什么这样做:

select custid, companyname
from sales.customers as c
where exists
(select orderid
from sales.orders as o
where c.custid = o.custid and o.orderdate = '20070212')

这不是

select custid, companyname
from sales.customers as c
where custid in
(select orderid
from sales.orders as o
where c.custid = o.custid and o.orderdate = '20070212')

什么时候应该使用什么?

1 个答案:

答案 0 :(得分:3)

在您使用exists子句的第一个查询中,实际上您在子查询中选择的内容无关紧要,它只是检查子查询中是否存在行。您可以选择NULL,它也可以正常工作:

select custid, companyname
  from sales.customers as c
 where exists (select null -- doesn't matter what you select
                 from sales.orders as o
                where c.custid = o.custid 
                  and o.orderdate = '20070212')

但是,在使用in子句的第二个查询中,子查询中返回的列很重要。虽然我们对您的表结构和数据一无所知,但列名称清楚地表明您在子查询中选择了错误的列(... where custid in (select orderid ...)。 (为什么要将客户ID与订单ID进行比较?)

事实上,如果你打算使用in子句,那么拥有相关子查询也没有意义,这有点多余。所以它可能看起来像这样:

select custid, companyname
  from sales.customers as c
 where c.custid in (select o.custid
                    from sales.orders as o
                   where o.orderdate = '20070212')

显然,我对您的数据知之甚少,但对于这种类型的查询,使用带有相关子查询的exists子句通常是更好的选择。与任何事情一样,检查并比较不同的执行计划并选择最佳执行计划。

关于何时选择inexists的一般指导原则,已有大量精彩文章,包括SO。谷歌搜索并不困难。