SQL不存在的地方



我认为我对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
)

我认为它应该返回:

1, 1, 1

但它却一无所获。

我之所以做出这个假设,是因为我认为NOT EXISTS会给我一个第一个查询中不存在于第二个查询中的所有行的列表(在这种情况下为1,1,1)

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

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

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 Server有一个EXCEPT运算符,其作用与Oracle的MINUS相同。其他一些数据库实现了其中的一个或另一个。

EXISTS仅在结果集中存在记录时返回true;它不进行任何值检查。由于子查询返回一条记录,因此EXISTS为true,NOT EXISTS为false,结果中没有记录。

通常,在子查询中有一个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
)

包含从对偶中选择的不存在将永远不会返回任何内容。不存在将排除嵌入SQL返回某些内容的行。通常不存在应该更像这样使用:

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

因为使用NOT EXISTS不是一个好方法,因为它只返回单行,所以请尝试使用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 )

最新更新