我遇到了一个虚构的SQL,我不确定原来的意图是什么,它看起来像:
SELECT COUNT (*)
INTO miss
FROM billing b
WHERE b.network= network1
and NOT EXISTS (SELECT 1 from vas NV WHERE NV.network =
b.network);
为什么选择1而不存在?
答案 0 :(得分:20)
当使用EXISTS
关键字时,您需要有一个子选择语句,并且只检查是否存在行,该行的内容无关紧要。 SELECT
是一个关键字,用于控制返回的列内的内容。 SELECT
1
或NV.network
将返回相同的行数。
因此,您可以选择任何您想要的内容,而规范的方法包括SELECT NULL
或SELECT 1
。
请注意,您的查询的替代方法是:
SELECT count(*) INTO miss
FROM billing b
LEFT JOIN vas NV ON NV.network = b.network
WHERE b.network = network1
AND NV.network IS NULL
(当NULL
条件无法匹配时,左连接会使用ON
值填充右侧列。
答案 1 :(得分:11)
SELECT 1 from vas NV WHERE NV.network = b.network
如果此查询返回一行,则表示NV表中的记录与记帐表中的记录匹配。
NOT EXISTS否定它,如果NV表中没有与记帐表中的记录匹配的记录,则满足WHERE子句。
答案 2 :(得分:6)
关于使用EXISTS与IN(或NOT EXISTS vs NOT IN)的问题,有一个很好的AskTom Q& A:
http://asktom.oracle.com/pls/asktom/f?p=100:11:1371782877074057::::P11_QUESTION_ID:953229842074
基本上使用EXISTS只检查子选择中是否存在行,并且不检查每个匹配的行(IN会这样做)。因此,当使用EXISTS或NOT EXISTS时,您不需要实际选择特定值,因此选择占位符(在本例中为“1”)就足够了。
在您的特定SQL语句中,NOT EXISTS子句确保主SELECT只返回VAS表中没有相应行的行。
答案 3 :(得分:2)
您的此代码主要是从性能角度编写的
我只提到内部查询。因为它需要用户解释。我用过的sql应插入用户上面使用的实际查询
and NOT EXISTS (SELECT 1 from vas NV WHERE NV.network =
b.network);
仅解释内部查询
通常人们会使用放置select NV.netword
但这会返回一个数据,该数据仅用于识别是否存在数据。因此,理想情况下,在内部查询中返回的内容甚至不会在父查询中进行检查。因此,为了减少解释计划中的字节数,我们使用select 1
,它将具有最小字节成本,从而降低查询成本。
要查看差异,我建议下载 oracle sql developer 并在解释计划窗口中同时运行查询并注意每个查询的bytes列
SELECT nv.network from vas NV WHERE NV.network = b.network
// cost will be depended on the value nv.network contain and that is selected in the where condition
而
SELECT 1 from vas NV WHERE NV.network = b.network
// cost will be independent of the column and cost lesser bytes selected and lesser cost.
不存在,您可以查看其他答案。