PostgreSQL provides special functions for creating array indices :
WITH x(a) AS ( VALUES ('{1,20,3,5}'::int[]) ) SELECT generate_subscripts(a, 1) AS idx ,unnest(a) AS val FROM x;
In fact, it is almost the same as the @Frank request, just without a subquery.
In addition, it works with indexes that do not start with 1 .
Or the solution works only for one-dimensional arrays! (It can be easily expanded to several dimensions.)
Functions:
CREATE OR REPLACE FUNCTION unnest_with_idx(anyarray) RETURNS TABLE(idx integer, val anyelement) LANGUAGE SQL IMMUTABLE AS $func$ SELECT generate_subscripts($1, 1), unnest($1); $func$;
Call:
SELECT * FROM unnest_with_idx('{1,20,3,5}'::int[]);
Also consider:
SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);
Read more about array indices in this related question .
If you really need normalized indexes (starting at 1), I would use:
SELECT generate_series(1, array_length($1,1) ) ...
This is almost a query that you already had, only with array_length() instead of array_upper() - which would not succeed with non-standard indexes.
Performance
I checked a quick test for an array of 1000 int with all the sentences requested here. They all do roughly the same thing (~ 3.5 ms) - with the exception of row_number() in the subquery (~ 7.5 ms) - as expected, due to the subquery.
Update: Postgres 9.4 +
If you are working with custom indexes, use the new WITH ORDINALITY :
- PostgreSQL unsest () with item number