存在和条件之间的区别在哪里

时间:2015-02-04 17:03:37

标签: sql sql-server

我对Where子句中的条件与存在与否之间的区别存在疑问。我知道当我使用第一种或第二种方式时,我不会得到相同的结果,但有人在乎解释原因吗?

例如,

SELECT ACCOUNT_NO,
       CLIENT_NAME
FROM   ACCOUNT a
       LEFT JOIN CLIENT b
              ON a.ACCOUNT_NO = b.ACCOUNT_NO
WHERE  ACCOUNT_TYPE NOT IN ( 'A', 'B', 'C' ) 

SELECT ACCOUNT_NO,
       CLIENT_NAME
FROM   ACCOUNT a
       LEFT JOIN CLIENT b
              ON a.ACCOUNT_NO = b.ACCOUNT_NO
WHERE  NOT EXISTS (SELECT *
                   FROM   ACCOUNT_DET t1
                          LEFT JOIN ACCOUNT t2
                                 ON t1.ACCOUNT_NO = t2.ACCOUNT_NO
                   WHERE  ACCOUNT_TYPE NOT IN ( 'A', 'B', 'C' )) 

我希望你了解我,表ACCOUNT_DET的字段几乎与ACCOUNT相同,但这是一个比我使用的更简化的查询。

1 个答案:

答案 0 :(得分:2)

这些是完全不同的查询。

让我们忽略与CLIENT的左连接,这两种情况都是相同的。

第一个查询可以描述为:

  

返回A,B或C以外类型的所有帐户。

第二个问题:

  

如果内部查询(在ACCOUNT_DET和ACCOUNT之间)返回 no 行,则返回ACCOUNT中的每条记录。如果内部查询的结果至少有一行,则不返回任何内容。

因此,实质上,EXISTS被评估为真或假。它等同于以下查询之一:

-- no rows returned by the inner query
Select ACCOUNT_NO, CLIENT_NAME 
From ACCOUNT a left join CLIENT b on a.ACCOUNT_NO=b.ACCOUNT_NO
Where NOT <false condition>

-- At least one row returned by the inner query
Select ACCOUNT_NO, CLIENT_NAME 
From ACCOUNT a left join CLIENT b on a.ACCOUNT_NO=b.ACCOUNT_NO
Where NOT <true condition>

使用内部查询过滤结果集

我猜您的目的是让主要和内部查询相关,这样您就可以过滤主查询的每条记录。为此,您可以使用内部查询中的主查询里面的表别名

一个简单的例子可能是:

select * from ACCOUNT A
where EXISTS( select * from ACCOUNT_DET D WHERE D.ACCOUNT_TYPE = A.ACCOUNT_TYPE)

注意内部查询如何使用主查询中定义的别名“A”,因此每个外部行都可以与内部查询相关。

¿哪个更好?

但是,这也可以通过连接来实现。我建议避免内部查询,其中连接可以在可读性和性能方面完成工作。