sql >> Databáze >  >> RDS >> PostgreSQL

Jak získat přístup k internímu indexu pole pomocí postgreSQL?

PostgreSQL dělá poskytují vyhrazené funkce pro generování dolních indexů pole:

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

Efektivně dělá téměř totéž jako dotaz @Frank, akorát bez poddotazu.
Navíc funguje s dolními indexy, které nezačínají 1 .

Obě řešení fungují pro jednorozměrné pouze pole! (Lze snadno rozšířit na více rozměrů.)

Funkce:

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

Volejte:

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

Zvažte také:

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

Více o dolních indexech pole v této související otázce.

Pokud ve skutečnosti chcete normalizované indexy (začínající 1), použil bych:

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

To je téměř ten dotaz, který jste již měli, jen s array_length() místo array_upper() - což by selhalo s nestandardními indexy.

Výkon

Provedl jsem rychlý test na poli 1000 int se všemi zde dosud prezentovanými dotazy. Všechny fungují přibližně stejně (~ 3,5 ms) – kromě row_number() na dílčí dotaz (~ 7,5 ms) - podle očekávání kvůli dílčímu dotazu.

Aktualizace:Postgres 9.4+

Pokud nepracujete s nestandardními indexovými indexy, použijte nový WITH ORDINALITY místo toho:

  • PostgreSQL unnest() s číslem prvku


  1. Jak používat _COUNT v BaseColumns

  2. Mapování pole pomocí režimu spánku

  3. Jak vložit do stejné tabulky v MySQL?

  4. MariaDB – MySQL – Zobrazení všech dostupných a podporovaných motorů