PostgreSQL doet bieden speciale functies om array-subscripts te genereren:
WITH x(a) AS ( VALUES ('{1,20,3,5}'::int[]) )
SELECT generate_subscripts(a, 1) AS idx
,unnest(a) AS val
FROM x;
In feite doet het bijna hetzelfde als de zoekopdracht van @Frank, alleen zonder subquery.
Bovendien werkt het met subscripts die niet beginnen met 1
.
Beide oplossingen werken voor 1-dimensionaal alleen arrays! (Kan eenvoudig worden uitgebreid tot meerdere dimensies.)
Functie:
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$;
Bel:
SELECT * FROM unnest_with_idx('{1,20,3,5}'::int[]);
Overweeg ook:
SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);
Meer over array-subscripts in deze gerelateerde vraag.
Als je eigenlijk genormaliseerde subscripts wilt (beginnend met 1), zou ik gebruiken:
SELECT generate_series(1, array_length($1,1)) ...
Dat is bijna de vraag die je al had, alleen met array_length()
in plaats van array_upper()
- wat zou mislukken met niet-standaard subscripts.
Prestaties
Ik heb een snelle test uitgevoerd op een array van 1000 int met alle vragen die hier tot nu toe zijn gepresenteerd. Ze presteren allemaal ongeveer hetzelfde (~ 3,5 ms) - behalve row_number()
op een subquery (~ 7,5 ms) - zoals verwacht, vanwege de subquery.
Update:Postgres 9.4+
Tenzij u werkt met niet-standaard index-subscripts, gebruikt u de nieuwe WITH ORDINALITY
in plaats daarvan:
- PostgreSQL unnest() met elementnummer