IN
和ANY
运算符在PostgreSQL中有什么区别?
这两者的工作机制似乎是相同的。有人能举个例子来解释一下吗?
IN
和ANY
运算符在PostgreSQL中有什么区别?
这两者的工作机制似乎是相同的。有人能举个例子来解释一下吗?
(严格来说,IN
和 ANY
是Postgres的“构造”或“语法元素”,而不是“操作符”。)
从逻辑上讲,引用手册:
IN
等效于= ANY
。
但是 IN
有两个语法变体,ANY
也有两个变体。详情如下:
采用一个集合的 IN
等同于采用一个集合的 = ANY
,如下所示:
但是每个构造的第二种变体略有不同。第二种 ANY
构造采用一个数组(必须是实际的数组类型),而 IN
的第二种变体采用逗号分隔的值列表。这会导致在传递值时有不同的限制,在特定情况下还可能导致不同的查询计划:
ANY
更加通用ANY
构造更加通用,因为它可以与各种操作符组合使用,而不仅仅是 =
。例如:
SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');
对于大量的值,提供一个集合在每个方面都更好:
相关:
"查找在给定数组中的id
行":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Inversion: "查找数组中不包含id
的行":
SELECT * FROM tbl WHERE id <> ALL (ARRAY[1, 2]);
SELECT * FROM tbl WHERE id <> ALL ('{1, 2}'); -- equivalent array literal
SELECT * FROM tbl WHERE NOT (id = ANY ('{1, 2}'));
所有三个等效。第一个使用数组构造器,其他两个使用数组字面值。未经类型标注的数组字面值的类型是从(已知)左边元素类型派生出来的。
在其他情况下(已有类型的数组值/需要不同类型/非默认类型的数组构造器),您可能需要显式转换。
id IS NULL
的行也不会通过这些表达式。要额外包含NULL
值:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;
SELECT * from mytable where id in (1, 2, 3)
和SELECT * from mytable where id = ANY('{1, 2, 3}')
将始终返回相同的行,即使它们可能有不同的查询计划。 - KPDANY
不能 与 !=
运算符结合使用。我认为这并没有被记录在文档中,但是 select * from foo where id != ANY (ARRAY[1, 2])
与 select * from foo where id NOT IN (1, 2)
不同。另一方面,select * from foo where NOT (id = ANY (ARRAY[1, 2]))
的效果如预期。 - qrisANY
可以和 !=
运算符结合使用,但这并不是全部。我在上面添加了一个章节。(请注意,在标准 SQL 中 < >
是运算符,尽管在 Postgres 中也接受 !=
。) - Erwin Brandstetter(id = ...) IS NOT TRUE
之所以有效是因为 id = ...
只有在实际匹配时才会计算为 TRUE
。结果为 FALSE
或 NULL
也会通过我们的测试。参见:https://dev59.com/K2Ag5IYBdhLWcg3wS5WC#23767625。您添加的表达式测试的是其他内容。这将等同于 WHERE id <> ALL (ARRAY [1, 2]) OR id IS NULL;
。 - Erwin Brandstetter除了另一个答案中提到的点外,还有两个明显的观点:
在使用子查询时它们是完全等效的:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);
另一方面:
仅IN
运算符允许使用简单的列表:
SELECT * FROM table
WHERE column IN(… , … , …);
在假定它们完全相同的情况下,有几次我会犯错,因为忘记了 ANY
不能与列表一起使用。
WHERE id = ANY(array[1,2])
就可以了。 - undefinedWHERE id = ANY(array(<子查询>))
。 - undefined'in'
是语法糖,你可以查看计划分析,会发现 'in'
会被转换为 =ANY('...,...')::yourType[]
IN
约束(来自子查询的值)执行需要26秒,但当我切换到一个= ANY(array(<subquery>))
时,相同的查询只需要几百毫秒。查询计划明显发生了变化。PG 12.3 - undefined