Oracle SQL中!= ANY(...)与NOT IN(...)的差异及等值查询疑问
关于SQL中
ANY/IN运算符的等价性与逻辑差异 这是个非常好的问题,刚好戳中了SQL里ANY(或SOME,两者是同义词)和IN运算符容易混淆的逻辑细节,我来给你拆解清楚:
1. = ANY和IN的等价性:你的认知完全正确!
你提到的这两个等值查询:
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');
功能上是完全等价的。SQL标准里,IN (val1, val2, val3)本质就是= ANY (val1, val2, val3)的语法糖,两者都会匹配字段值等于集合中任意一个元素的记录,所以返回结果完全一致,你的判断没问题。
2. 为什么!= ANY和NOT IN表现天差地别?
这核心是逻辑判断的范围不同:
!= ANY ('A','B','C')的逻辑是:只要字段值不等于集合里的某一个元素,条件就成立。举个例子:- 如果字段值是'A',它不等于'B'和'C',所以这个条件为真,会被返回;
- 如果字段值是'B',它不等于'A'和'C',条件也为真,会被返回;
- 哪怕字段值是'C',它不等于'A'和'B',条件还是为真,会被返回;
- 更别说其他不在集合里的值了,自然也会被返回。
这就是为什么你用这个查询会得到所有记录,包括等于'A'/'B'/'C'的。
NOT IN ('A','B','C')的逻辑是:字段值不等于集合里的所有元素(也就是完全不在这个集合中),这才是你最初想要的“排除这三个值”的逻辑。
补充:和NOT IN等价的写法
如果想用ANY的同类运算符实现NOT IN的效果,应该用!= ALL(或<> ALL):
select * from FOO_TABLE ft where ft.foo_field != all ('A','B','C');
!= ALL的逻辑是:字段值必须不等于集合里的每一个元素,和NOT IN的逻辑完全一致,执行结果也会符合你的预期。
内容的提问来源于stack exchange,提问作者Sir Jo Black
相关产品推荐
相关产品推荐

