【问题标题】:IN vs ANY operator in PostgreSQLPostgreSQL 中的 IN 与 ANY 运算符
【发布时间】:2016-04-10 04:24:00
【问题描述】:

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

【问题讨论】:

标签: sql database postgresql rdbms sql-in


【解决方案1】:

INANY 都不是“运算符”。“构造”或“语法元素”。)

逻辑上quoting the manual

IN 等价于= ANY

但是IN 有两个语法变体ANY 有两个变体。详情:

IN 接受一个集合相当于= ANY接受一个集合,如下所示:

但每个变体的第二个变体并不等同于另一个。 ANY 构造的第二个变体采用 array(必须是实际的数组类型),而 IN 的第二个变体采用逗号分隔的 值列表。这导致传值的限制不同,可以在特殊情况下也会导致不同的查询计划:

ANY 更通用

ANY 结构更加通用,因为它可以与各种运算符组合,而不仅仅是=。示例:

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

对于大量值,提供 set 可以更好地扩展每个值:

相关:

反转/相反/排除

“查找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 可以与!= 运算符结合使用。但还有更多。我在上面添加了一章。 (请注意,&lt;&gt; 是标准 SQL 中的运算符 - 尽管 Postgres 也接受 !=。)
  • 最后一个包含NULL 值的版本是如何工作的? WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL; 也能正常工作吗?
  • @dvtan: (id = ...) IS NOT TRUE 有效,因为id = ... 仅在存在实际匹配时才计算为TRUE。结果FALSENULL 通过了我们的测试。见:stackoverflow.com/a/23767625/939860。您添加的表达式测试其他内容。这相当于WHERE id &lt;&gt; 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 不适用于列表时,假设它们完全相同,这让我好几次感到困惑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    相关资源
    最近更新 更多