PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come accedere all'indice interno dell'array con postgreSQL?

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