我对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相同,但这是一个比我使用的更简化的查询。
答案 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”,因此每个外部行都可以与内部查询相关。
但是,这也可以通过连接来实现。我建议避免内部查询,其中连接可以在可读性和性能方面完成工作。