PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment accéder à l'index interne du tableau avec postgreSQL ?

PostgreSQL fait fournissent des fonctions dédiées pour générer des indices de tableau :

WITH   x(a) AS ( VALUES ('{1,20,3,5}'::int[]) )
SELECT generate_subscripts(a, 1) AS idx
      ,unnest(a) AS val
FROM   x;

En fait, cela fait presque la même chose que la requête de @Frank, mais sans sous-requête.
De plus, cela fonctionne avec des indices qui ne commencent pas par 1 .

L'une ou l'autre solution fonctionne pour 1-dimensionnel tableaux uniquement ! (Peut facilement être étendu à plusieurs dimensions.)

Fonction :

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$;

Appel :

SELECT * FROM unnest_with_idx('{1,20,3,5}'::int[]);

Considérez également :

SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);

Plus d'informations sur les indices de tableau dans cette question connexe.

Si vous voulez en fait des indices normalisés (commençant par 1), j'utiliserais :

SELECT generate_series(1, array_length($1,1)) ...

C'est presque la requête que vous aviez déjà, juste avec array_length() au lieu de array_upper() - qui échouerait avec des indices non standard.

Performances

J'ai effectué un test rapide sur un tableau de 1000 int avec toutes les requêtes présentées ici jusqu'à présent. Ils fonctionnent tous à peu près de la même manière (~ 3,5 ms) - à l'exception de row_number() sur une sous-requête (~ 7,5 ms) - comme prévu, à cause de la sous-requête.

Mise à jour :Postgres 9.4+

Sauf si vous travaillez avec des indices d'index non standard, utilisez le nouveau WITH ORDINALITY à la place :

  • PostgreSQL unnest() avec le numéro d'élément