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


我经常使用 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);

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

错误:运算符不存在: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小提琴

那么我做错了什么?


1842
2017-09-01 07:14


起源



答案:


基于错误消息部分 operator does not exist: integer = integer[],它似乎 bs 专栏需要 unnested,为了让右手边回到 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);

这导致输出:

A
2
3

鉴于该文件 任何功能

右侧是带括号的子查询,必须返回   正好一列。评估并比较左手表达   使用给定的运算符到子查询结果的每一行   必须产生布尔结果。如果有的话,任何结果都是“真实的”   得到的结果。如果未找到真实结果,则结果为“false”   (包括子查询不返回任何行的情况)。

......错误是有道理的,因为左手表达是一个 integer  - 专栏 b  - 而右手表达式是一个数组 integers,或 integer[],因此比较最终成为形式 integer = integer[],没有运算符,因此导致错误。

unnestinteger[] value产生左手和右手的表达式 integers,所以比较可以继续。

改性 SQL小提琴

注意: 使用时会看到相同的行为 IN 代替 = ANY


13
2017-09-01 07:41



根据你的答案补充说明:因为 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 并且解析器不够聪明,无法确定只有一个是合法的。你可以告诉它你真的想要数组-ANY形式 1 = ANY( (SELECT ARRAY[1,2,3])::int[] ) (我会这样做而不是 unnest荷兰国际集团)。 - Craig Ringer
啊,有趣。感谢您提供更多详情。 - khampson
@CraigRinger:谢谢! Ken的回答帮助我如何正确地做到了,但是你的评论让我理解为什么我的查询错了。 - Pavel V.


答案:


基于错误消息部分 operator does not exist: integer = integer[],它似乎 bs 专栏需要 unnested,为了让右手边回到 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);

这导致输出:

A
2
3

鉴于该文件 任何功能

右侧是带括号的子查询,必须返回   正好一列。评估并比较左手表达   使用给定的运算符到子查询结果的每一行   必须产生布尔结果。如果有的话,任何结果都是“真实的”   得到的结果。如果未找到真实结果,则结果为“false”   (包括子查询不返回任何行的情况)。

......错误是有道理的,因为左手表达是一个 integer  - 专栏 b  - 而右手表达式是一个数组 integers,或 integer[],因此比较最终成为形式 integer = integer[],没有运算符,因此导致错误。

unnestinteger[] value产生左手和右手的表达式 integers,所以比较可以继续。

改性 SQL小提琴

注意: 使用时会看到相同的行为 IN 代替 = ANY


13
2017-09-01 07:41



根据你的答案补充说明:因为 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 并且解析器不够聪明,无法确定只有一个是合法的。你可以告诉它你真的想要数组-ANY形式 1 = ANY( (SELECT ARRAY[1,2,3])::int[] ) (我会这样做而不是 unnest荷兰国际集团)。 - Craig Ringer
啊,有趣。感谢您提供更多详情。 - khampson
@CraigRinger:谢谢! Ken的回答帮助我如何正确地做到了,但是你的评论让我理解为什么我的查询错了。 - Pavel V.


列需要是不需要的

带栏AS(   SELECT array_agg(b)AS bs   来自foo   在哪里c <3 ) 选择一个 来自foo WHERE b = ANY(SELECT unnest(bs)FROM bar);


0
2017-11-30 06:55



这与现有答案有何不同? - a_horse_with_no_name


没有消除

WITH bar AS (
  SELECT array_agg(b) AS bs
  FROM foo
  WHERE c < 3
)
SELECT a FROM foo WHERE ( SELECT b = ANY (bs) FROM bar);

0
2017-12-01 15:19