sql >> Database >  >> RDS >> PostgreSQL

Hoe toegang krijgen tot de interne array-index met postgreSQL?

PostgreSQL doet bieden speciale functies om array-subscripts te genereren:

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

In feite doet het bijna hetzelfde als de zoekopdracht van @Frank, alleen zonder subquery.
Bovendien werkt het met subscripts die niet beginnen met 1 .

Beide oplossingen werken voor 1-dimensionaal alleen arrays! (Kan eenvoudig worden uitgebreid tot meerdere dimensies.)

Functie:

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

Bel:

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

Overweeg ook:

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

Meer over array-subscripts in deze gerelateerde vraag.

Als je eigenlijk genormaliseerde subscripts wilt (beginnend met 1), zou ik gebruiken:

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

Dat is bijna de vraag die je al had, alleen met array_length() in plaats van array_upper() - wat zou mislukken met niet-standaard subscripts.

Prestaties

Ik heb een snelle test uitgevoerd op een array van 1000 int met alle vragen die hier tot nu toe zijn gepresenteerd. Ze presteren allemaal ongeveer hetzelfde (~ 3,5 ms) - behalve row_number() op een subquery (~ 7,5 ms) - zoals verwacht, vanwege de subquery.

Update:Postgres 9.4+

Tenzij u werkt met niet-standaard index-subscripts, gebruikt u de nieuwe WITH ORDINALITY in plaats daarvan:

  • PostgreSQL unnest() met elementnummer


  1. SqlDateTime.MinValue !=DateTime.MinValue, waarom?

  2. Mysql localhost !=127.0.0.1?

  3. SSIS-zelfstudie voor beginners:waarom, wat en hoe?

  4. Hoe repliceer je alleen INSERT's en niet DELETEs/UPDATEs op Slony Slave Node?