The first error is due to the fact that PostgreSQL sees
num = ANY(SELECT array_agg(num) from test)
as a form of
expression operator ANY (subquery)
instead of the one you want:
expression operator ANY (array expression)
As such, it tries to compare num
to any ROW returned by the subquery (which in your example returns a single row ARRAY[1,2]
), instead of every element of the array (hence the operator does not exist: integer = integer[]
error you're getting). See the documentation for more details.
The second errors simply comes from the fact that [0]
accesses an element of an integer[]
, and as such returns an integer
. Since the right operand has to be an array (or a subquery, but PostgreSQL can't see one here), PostgreSQL returns ERROR: op ANY/ALL (array) requires array on right side
.
(As an aside, arrays are 1-based in PostgreSQL, not 0-based).
If you are sure that your function will always return a single array, then you can simply force Postgre to see SELECT array_agg(num) from test
as an integer[]
:
SELECT * FROM test
WHERE num = ANY((SELECT array_agg(num) from test)::integer[]);
┌─────┐
│ num │
├─────┤
│ 1 │
│ 2 │
└─────┘
(2 rows)
Note however that if your function returns multiple arrays, you will get an error (since a setof integer[]
cannot be seen as an integer[]
):
SELECT * FROM test
WHERE num = ANY((SELECT array_agg(num) from test GROUP BY num)::integer[]);
ERROR: 21000: more than one row returned by a subquery used as an expression
LOCATION: ExecSetParamPlan, nodeSubplan.c:970
Another solution is to use the unnest
function to transform your array to a set of integer, using the expression operator ANY (subquery)
form. This will work even if your function returns multiple array, though it is a bit slower than the previous query.
SELECT *
FROM test
WHERE num = ANY(
SELECT unnest(sub.array_agg)
FROM (
SELECT array_agg(num) FROM test GROUP BY num -- GROUP BY num to show off the multiple array scenario
) AS sub
);
┌─────┐
│ num │
├─────┤
│ 1 │
│ 2 │
└─────┘
(2 rows)