PostgreSQL 中的 IN 与 ANY 运算符
Posted
技术标签:
【中文标题】PostgreSQL 中的 IN 与 ANY 运算符【英文标题】:IN vs ANY operator in PostgreSQL 【发布时间】:2016-04-10 04:24:00 【问题描述】:PostgreSQL 中IN
和ANY
运算符有什么区别?
两者的工作机制似乎是一样的。谁能举个例子解释一下?
【问题讨论】:
postgreSQL - in vs any的可能重复 这能回答你的问题吗? Difference between in and any operators in sql 【参考方案1】:(IN
和 ANY
都不是“运算符”。“构造”或“语法元素”。)
逻辑上,quoting the manual:
IN
等价于= ANY
。
但是IN
有两个语法变体,ANY
有两个变体。详情:
IN
接受一个集合相当于= ANY
接受一个集合,如下所示:
但每个变体的第二个变体并不等同于另一个。 ANY
构造的第二个变体采用 array(必须是实际的数组类型),而 IN
的第二个变体采用逗号分隔的 值列表。这导致传值的限制不同,可以在特殊情况下也会导致不同的查询计划:
=any()
but used with in
Pass multiple sets or arrays of values to a function
How to match elements in an array of composite type?
ANY
更通用
ANY
结构更加通用,因为它可以与各种运算符组合,而不仅仅是=
。示例:
SELECT 'foo' LIKE ANY('FOO,bar,%oo%');
对于大量值,提供 set 可以更好地扩展每个值:
Optimizing a Postgres query with a large IN相关:
Can PostgreSQL index array columns?反转/相反/排除
“查找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 constructor,另外两个是array literal。数据类型可以明确地从上下文中派生。否则,可能需要显式转换,例如 '1,2'::int[]
。
带有 id IS NULL
的行不会通过这些表达式中的任何一个。额外包含NULL
值:
SELECT * FROM tbl WHERE (id = ANY ('1, 2')) IS NOT TRUE;
【讨论】:
最好明确说明第二个变体的结果总是相同的。我有 99% 的把握确实是这样,但答案似乎并没有说明这一点。这意味着SELECT * from mytable where id in (1, 2, 3)
将始终产生与SELECT * from mytable where id = ANY('1, 2, 3')
相同的行,即使它们可能具有不同的查询计划。
ANY
不能与!=
运算符结合使用。我认为它没有记录在案,但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]))
按预期工作。
@qris: ANY
可以与!=
运算符结合使用。但还有更多。我在上面添加了一章。 (请注意,<>
是标准 SQL 中的运算符 - 尽管 Postgres 也接受 !=
。)
最后一个包含NULL
值的版本是如何工作的? WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;
也能正常工作吗?
@dvtan: (id = ...) IS NOT TRUE
有效,因为id = ...
仅在存在实际匹配时才计算为TRUE
。结果FALSE
或NULL
通过了我们的测试。见:***.com/a/23767625/939860。您添加的表达式测试其他内容。这相当于WHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
【参考方案2】:
有两个明显的点,以及另一个答案中的点:
在使用子查询时,它们是完全等价的:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);
另一方面:
只有IN
运算符允许简单列表:
SELECT * FROM table
WHERE column IN(… , … , …);
当我忘记ANY
不适用于列表时,假设它们完全相同,这让我好几次感到困惑。
【讨论】:
以上是关于PostgreSQL 中的 IN 与 ANY 运算符的主要内容,如果未能解决你的问题,请参考以下文章