PostgreSQL中的IN和ANY运算符有什么区别? 两者的工作机制似乎是一样的。有人能举个例子解释一下吗?


当前回答

(严格来说,IN和ANY是Postgres的“构造”或“语法元素”,而不是“操作符”。)

逻辑上,引用手册:

IN相当于= ANY。

但是有两个IN的语法变体和两个ANY的语法变体。细节:

在WHERE子句中如何使用ANY而不是IN ?

IN取一个集合等价于= ANY取一个集合,如下所示:

在与任何

但两者的第二种变体略有不同。ANY构造的第二个变体接受一个数组(必须是实际的数组类型),而IN的第二个变体接受一个以逗号分隔的值列表。这导致在传递值时有不同的限制,也可能导致在特殊情况下有不同的查询计划:

索引不与=any()一起使用,而是与in一起使用 将多个值集或数组传递给函数 如何匹配复合类型数组中的元素?

ANY更通用

ANY结构要通用得多,因为它可以与各种操作符组合,而不仅仅是=。例子:

SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');

对于大量的值,为每个值提供一组更好的伸缩性:

使用大IN优化Postgres查询

相关:

PostgreSQL可以索引数组列吗?

颠倒/相反/排斥

"查找id在给定数组中的行":

SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);

反转:"查找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}'));

三个都是等价的。第一个使用ARRAY构造函数,其他两个使用数组文字。无类型数组文字的类型是从左边的(已知)元素类型派生出来的。 在其他星座中(类型化的数组值/您想为非默认类型使用不同的类型/ array构造函数),您可能需要显式强制转换。

id为空的行不会传递这两个表达式。额外包含NULL值:

SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;

其他回答

这里有两个明显的观点,和另一个答案中的观点一样:

它们在使用子查询时是完全等价的: SELECT * FROM表 WHERE列IN(子查询); SELECT * FROM表 WHERE column = ANY(子查询);

另一方面:

只有IN操作符允许一个简单的列表: SELECT * FROM表 WHERE column IN(…,…,…);

假设它们是完全相同的,这让我好几次忘记ANY不能与列表一起工作。

(严格来说,IN和ANY是Postgres的“构造”或“语法元素”,而不是“操作符”。)

逻辑上,引用手册:

IN相当于= ANY。

但是有两个IN的语法变体和两个ANY的语法变体。细节:

在WHERE子句中如何使用ANY而不是IN ?

IN取一个集合等价于= ANY取一个集合,如下所示:

在与任何

但两者的第二种变体略有不同。ANY构造的第二个变体接受一个数组(必须是实际的数组类型),而IN的第二个变体接受一个以逗号分隔的值列表。这导致在传递值时有不同的限制,也可能导致在特殊情况下有不同的查询计划:

索引不与=any()一起使用,而是与in一起使用 将多个值集或数组传递给函数 如何匹配复合类型数组中的元素?

ANY更通用

ANY结构要通用得多,因为它可以与各种操作符组合,而不仅仅是=。例子:

SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');

对于大量的值,为每个值提供一组更好的伸缩性:

使用大IN优化Postgres查询

相关:

PostgreSQL可以索引数组列吗?

颠倒/相反/排斥

"查找id在给定数组中的行":

SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);

反转:"查找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}'));

三个都是等价的。第一个使用ARRAY构造函数,其他两个使用数组文字。无类型数组文字的类型是从左边的(已知)元素类型派生出来的。 在其他星座中(类型化的数组值/您想为非默认类型使用不同的类型/ array构造函数),您可能需要显式强制转换。

id为空的行不会传递这两个表达式。额外包含NULL值:

SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;

'in'是句法糖,你可以看一下计划分析,会看到'in'将被转换为=ANY('…,…')::yourType[]