Oracle SQL子句“!= ANY(...)”和“ not IN(...)”之间有什么区别

时间:2020-01-30 11:07:47

标签: sql oracle

我使用了类似于以下内容的SQL查询:

select * from FOO_TABLE ft where ft.foo_field != any ('A','B','C');

我认为结果将是foo_field不包含'A'或'B'或'C'( exclusive )的所有记录,但我获得了所有记录作为结果foo_field等于“ A”,“ B”或“ C”。

为避免上述问题,我使用:

select * from FOO_TABLE ft where ft.foo_field not in ('A','B','C');

上面的查询按预期运行。

我经常使用以下查询来生成上述查询的逆查询(以获取包含“ A”或“ B”或“ C”的所有记录-包括):< / p>

select * from FOO_TABLE ft where ft.foo_field = any ('A','B','C');

select * from FOO_TABLE ft where ft.foo_field in ('A','B','C');

我认为我用作 inclusive 的两个查询之间没有结果差异。是真的!?

为什么“ 专有”查询的行为不同?

2 个答案:

答案 0 :(得分:1)

我认为您正在滥用NOT(!)运算符。

工作原理:

“ column_name = ANY(...)”:该值必须与一个或多个 列表以评估为TRUE。

“ column_name!= ANY(...)”:该值不能 匹配列表中的一个或多个值以求值为TRUE。

在您的情况下,您的列值可以说'A'=ANY('A','B','C')匹配,但是同时使用!=ANY('A','B','C')时,其值也将计算为TRUE A!=B or A!=C

因此,您必须使用column_name !=ALL('A','B','C')或使用NOT column_name =ANY('A','B','C'),如下所示:

可以使用

select * from FOO_TABLE ft where NOT ft.foo_field = any ('A','B','C'); 
 -- see the keyword NOT before column name

select * from FOO_TABLE ft where ft.foo_field != ALL ('A','B','C');

干杯!

答案 1 :(得分:1)

我相信使用<> ALL而不是<> IN等效。

考虑SQL中的此类构造时,可能要考虑的两个最重要的情况是:

  • 空集(只能使用子查询来生成)。
  • NULL值。

在两种情况下,in= any的行为方式相同。同样,not in<> all的行为方式相同。

我应该指出,如果子查询中有任何<> all,则NULL的行为可能与预期不符。在这种情况下,它什么也不返回。这就是为什么我推荐NOT EXISTS胜过NOT IN