PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie greife ich mit PostgreSQL auf den internen Index des Arrays zu?

PostgreSQL macht es dedizierte Funktionen zum Generieren von Array-Indizes bereitstellen:

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

Effektiv macht es fast dasselbe wie die Abfrage von @Frank, nur ohne Unterabfrage.
Außerdem funktioniert es mit Indizes, die nicht mit 1 beginnen .

Beide Lösungen funktionieren für 1-dimensional Nur Arrays! (Kann leicht auf mehrere Dimensionen erweitert werden.)

Funktion:

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

Aufruf:

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

Beachten Sie auch:

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

Mehr über Array-Indizes in dieser verwandten Frage.

Wenn Sie möchten eigentlich normalisierte Indizes (beginnend mit 1), ich würde verwenden:

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

Das ist fast die Abfrage, die Sie bereits hatten, nur mit array_length() statt array_upper() - was bei nicht standardmäßigen Indizes fehlschlagen würde.

Leistung

Ich habe einen Schnelltest mit einem Array von 1000 int mit allen bisher hier präsentierten Abfragen durchgeführt. Sie verhalten sich alle ungefähr gleich (~ 3,5 ms) - außer row_number() auf eine Unterabfrage (~ 7,5 ms) - wie erwartet, wegen der Unterabfrage.

Aktualisierung:Postgres 9.4+

Verwenden Sie das neue WITH ORDINALITY, es sei denn, Sie arbeiten mit nicht standardmäßigen Indexindizes stattdessen:

  • PostgreSQL unnest() mit Elementnummer