SQL 不存在的地方

SQL Where Not Exists

我想我对 NOT EXISTS 的工作原理有误解,希望能向我澄清一下。

下面是示例代码我是运行(也在SQL Fiddle

select sum(col1) col1, sum(col2) col1, sum(col3) col3
from (
  select 1 col1, 1 col2, 1 col3
  from dual tbl1
  )
where not exists(
  select 2 col1, 1 col2, 1 col3
  from dual tbl2
)

我认为应该 return:

1, 1, 1

但它return什么都不是。

我做出这个假设只是因为我虽然 NOT EXISTS 会给我一个列表,其中包含第一个查询中不存在于第二个查询中的所有行(在本例中为 1,1,1)

  1. 为什么这不起作用
  2. 使它按我期望的方式工作的适当方法是什么?

EXISTS 如果结果集中存在记录,则 returns 为真;它不做任何值检查。由于子查询returns一条记录,EXISTS为真,NOT EXISTS为假,结果没有记录。

通常您在子查询中有一个 WHERE 子句来将值与外部查询进行比较。

完成你想要的一个方法是使用EXCEPT:

select sum(col1) col1, sum(col2) col1, sum(col3) col3
from (
  select 1 col1, 1 col2, 1 col3
  from dual tbl1
  )
EXCEPT(
  select 2 col1, 1 col2, 1 col3
  from dual tbl2
)

您正在 NOT EXISTS() 条件下执行不相关的子查询。它总是 returns 恰好一行,因此永远不会满足 NOT EXISTS 条件,并且您的查询 returns 零行。

Oracle 有一个行集差异运算符 MINUS,它应该可以满足您的需求:

select sum(col1) col1, sum(col2) col1, sum(col3) col3
from (
  select 1 col1, 1 col2, 1 col3
  from dual tbl1

  MINUS

  select 2 col1, 1 col2, 1 col3
  from dual tbl2
)

SQL 服务器有一个 EXCEPT 运算符,其作用与 Oracle 的 MINUS 相同。其他一些数据库实现其中之一。

包含来自 dual 的 select 的不存在永远不会 return 任何东西。不存在将排除嵌入 SQL return 某些内容的行。通常不存在应该更像这样使用:

select ... from MY_TABLE A where not exists (select 1 from OTHER_TABLE B where A.SOME_COL = B.SOME_COL)

因为使用 NOT EXISTS 不是很好的方法,因为它 return 只有单行所以尝试使用 MINUSEXCEPT

select sum(col1) col1, sum(col2) col1, sum(col3) col3 from ( select 1 col1, 1 col2, 1 col3 from dual tbl1 MINUS select 2 col1, 1 col2, 1 col3 from dual tbl2 )

select sum(col1) col1, sum(col2) col1, sum(col3) col3 from ( select 1 col1, 1 col2, 1 col3 from dual tbl1 ) EXCEPT( select 2 col1, 1 col2, 1 col3 from dual tbl2 )