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[]
推荐文章
- 在SQL server查询中将NULL替换为0
- 在SQL中修改表的模式名
- 如何在SQL Server 2005的一条语句中更新两个表?
- 如何创建临时表与SELECT * INTO tempTable从CTE查询
- 用于查找计数为>的记录的SQL查询
- 使用PSQL命令查找主机名和端口
- “从Table1左连接Table2”和“从Table2右连接Table1”可以互换吗?
- 在SQL Server的选择语句中使用带TOP的变量,而不是动态的
- 自然连接和内部连接的区别
- MySQL现在()+1天
- 在SQL中转换月号到月名函数
- 改变一个varchar列的最大长度?
- 外键约束:何时使用ON UPDATE和ON DELETE
- 暂时关闭约束(MS SQL)
- WHERE子句中的IF子句