PostgreSQL fa fornire funzioni dedicate per generare indici di array:
WITH x(a) AS ( VALUES ('{1,20,3,5}'::int[]) )
SELECT generate_subscripts(a, 1) AS idx
,unnest(a) AS val
FROM x;
In effetti fa quasi lo stesso della query di @Frank, solo senza subquery.
Inoltre funziona con pedici che non iniziano con 1
.
Entrambe le soluzioni funzionano per monodimensionale solo array! (Può essere facilmente ampliato a più dimensioni.)
Funzione:
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$;
Chiama:
SELECT * FROM unnest_with_idx('{1,20,3,5}'::int[]);
Considera anche:
SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);
Maggiori informazioni sugli indici degli array in questa domanda correlata.
Se in realtà vuoi pedici normalizzati (a partire da 1), userei:
SELECT generate_series(1, array_length($1,1)) ...
Questa è quasi la query che avevi già, solo con array_length()
invece di array_upper()
- che fallirebbe con pedici non standard.
Prestazioni
Ho eseguito un rapido test su un array di 1000 int con tutte le query presentate qui finora. Funzionano tutti più o meno allo stesso modo (~ 3,5 ms) - ad eccezione di row_number()
su una sottoquery (~ 7,5 ms) - come previsto, a causa della sottoquery.
Aggiornamento:Postgres 9.4+
A meno che tu non operi con indici di indice non standard, usa il nuovo WITH ORDINALITY
invece:
- PostgreSQL unnest() con numero elemento