PostgreSQL中NOT ([col] = ANY [collection])与[col] != ALL [collection]的差异
在PostgreSQL中,
not ([col] = any [collection]) 与 [col] != all [collection] 的关系 先给个明确结论:在PostgreSQL的所有场景下,这两个表达式在逻辑上是完全等价的——它们会返回完全相同的结果,包括涉及NULL值的边缘情况。很多人会疑惑两者的差异,主要是对SQL三值逻辑和ANY/ALL运算符的行为理解不够清晰,下面我展开解释:
基础逻辑等价性
从纯逻辑角度看,这两个表达式是互为镜像的表述:
not ([col] = any [collection])代表:不存在集合中的任何元素等于col[col] != all [collection]代表:集合中的所有元素都不等于col
这两种说法本质是同一个意思——“没有任何一个元素匹配col”和“所有元素都不匹配col”是完全等价的逻辑判断。
涉及NULL值的行为(关键澄清)
很多人误以为NULL会导致两者结果不同,但实际上PostgreSQL对这两个表达式的NULL处理是完全一致的:
场景1:集合包含NULL,col为非NULL值
假设集合是ARRAY[2, NULL],col=1:
1 = any (ARRAY[2, NULL]):1和2不相等(false),1和NULL比较结果为NULL;ANY运算符只要有一个true就返回true,否则若存在NULL则返回NULL,所以这里结果是NULL。not (1 = any (...)):对NULL取反的结果还是NULL。1 != all (ARRAY[2, NULL]):1≠2是true,1≠NULL是NULL;ALL运算符需要所有比较结果都是true才返回true,只要存在NULL或false则返回NULL,所以这里结果也是NULL。
两者结果一致,均为NULL。
场景2:col是NULL,集合包含非NULL元素
假设集合是ARRAY[1,2],col=NULL:
NULL = any (ARRAY[1,2]):NULL和任何非NULL值比较都是NULL,ANY返回NULL。not (NULL = any (...)):结果为NULL。NULL != all (ARRAY[1,2]):NULL和任何非NULL值比较都是NULL,ALL返回NULL。
两者结果依然一致。
场景3:空集合
当集合是空的(比如空数组或返回空行的子查询):
col = any (空集合):返回false(没有元素能匹配)。not (col = any (空集合)):返回true。col != all (空集合):返回true(SQL中“所有元素满足条件”对空集合属于vacuous truth,即默认成立)。
结果还是完全一致。
为什么会有“存在差异”的误解?
这种误解通常来自对SQL三值逻辑的不熟悉,或是混淆了其他运算符(比如like)的行为。但对于=和!=搭配ANY/ALL的组合,PostgreSQL严格遵循逻辑等价性,不会出现结果差异。
内容的提问来源于stack exchange,提问作者Justin Borromeo
相关产品推荐
相关产品推荐

