2016-08-13 55 views
-3

为什么这项工作:IN VS EXIST子查询

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

什么时候应该用什么?

+0

它是抛出一个错误还是只是没有返回? –

+0

您需要提供示例数据和示例输出 – dbmitch

回答

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第2号查询,子查询返回的列是显著。虽然我们对表结构和数据一无所知,但列名很明显地表明您在子查询中选择了错误的列(... where custid in (select orderid ...)。 (为什么你比较客户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。在谷歌上不是一个困难的搜索。

+1

OP的注释:我会极力鼓励您*不*使用SELECT NULL作为相关的子查询,因为我认为'NULL'意味着某事存在。我通常使用'SELECT 1'。 –

+0

@戈登:嘿。我怀疑大多数人会同意你的看法。我个人复制了where存在的地方(从Oracle的Tom Kyte中选择null样式。[引用他](https://asktom.oracle.com/pls/apex/f?p = 100:11:0 :::: P11_QUESTION_ID:442029737684#5692820553867):*“我发现select null在语义上更有意义,你没有真正选择任何东西 - 所以这么说。”*我一直赞同并一直坚持这种风格。我也明白你的观点。 – sstan