运算符不存在:带有ANY的查询中的integer = integer []

Pav*_* V. 15 sql postgresql

我经常使用integer = ANY(integer[])语法,但现在任何运算符都不起作用.这是我第一次使用它来比较标量和从CTE返回的整数,但我认为这不应该导致问题.

我的查询:

WITH bar AS (
  SELECT array_agg(b) AS bs
  FROM foo
  WHERE c < 3
)
SELECT a FROM foo WHERE b = ANY ( SELECT bs FROM bar);
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它会抛出以下错误:

错误:运算符不存在:integer = integer []:WITH bar AS(SELECT array_agg(b)AS bs FROM foo WHERE c <3)SELECT a FROM foo WHERE b = ANY(SELECT bs FROM bar)

这个SQL小提琴的细节.

那么我做错了什么?

kha*_*son 20

基于错误消息部分operator does not exist: integer = integer[],似乎bs需要unnest编辑该列,以便将右侧返回到一个,integer以便可以找到比较运算符:

WITH bar AS (
  SELECT array_agg(b) AS bs
  FROM foo
  WHERE c < 3
)
SELECT a
FROM foo
WHERE b = ANY ( SELECT unnest(bs) FROM bar);
Run Code Online (Sandbox Code Playgroud)

这导致输出:

A
2
3
Run Code Online (Sandbox Code Playgroud)

鉴于ANY功能的文档:

右侧是带括号的子查询,它必须返回一列.使用给定运算符计算左侧表达式并将其与子查询结果的每一行进行比较,该运算符必须产生布尔结果.如果获得任何真实结果,则ANY的结果为"true".如果未找到真实结果,则结果为"false"(包括子查询不返回任何行的情况).

...错误是有道理的,因为左手表达式是integer- 列b- 而右手表达式是integers 的数组,或者integer[],因此比较最终是形式integer= integer[],这不是'有一个操作员,因此导致错误.

unnestinteger[]值使得左手和右手表达式成为integers,因此比较可以继续.

修改过的SQL小提琴.

注意:使用IN而不是使用相同的行为= ANY.

  • 基于你答案的补充说明:因为`1 = ANY(ARRAY [1,2,3])`是合法的,所以也期望`1 = ANY(SELECT ARRAY [1,2,3])`是合理的合法,但不是因为这会产生一种含糊不清的关于你是否想要'1 = ARRAY [1,2,3]`或'1 = 1 OR 1 = 2 OR 1 = 3`并且解析器不是聪明到足以弄清楚只有一个是合法的.你可以告诉它你真的想要一个带有`1 = ANY((SELECT ARRAY [1,2,3]):: int [])`的数组ANY形式(我会这样做而不是'免除'). (10认同)