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

Initial array i funktion til at aggregere multi-dimensional array

Postgres 9.5 eller nyere

... leveres med en ekstra variant af aggregatfunktionen array_agg() . Manualen:

input-arrays sammenkædet til array af en højere dimension (inputs skal alle have samme dimensionalitet og kan ikke være tomme eller nul)

Så ikke helt det samme som den tilpassede aggregerede funktion array_agg_mult() under. Men brug det, hvis du kan. Det er hurtigere.

Relateret:

  • Hvordan sorterer man todimensionelt int-array i PostgreSQL?

Postgres 9.4 eller ældre

Aggregeringsfunktion for enhver matrixtype

Med den polymorfe type anyarray det virker for alle slags arrays (inklusive integer[] ):

CREATE AGGREGATE array_agg_mult (anyarray) (
   SFUNC     = array_cat
 , STYPE     = anyarray
 , INITCOND  = '{}'
);

Som @Lukas leverede, den brugerdefinerede funktion arrayappend() er ikke nødvendig. Den indbyggede array_cat() gør jobbet. Det forklarer dog ikke hvorfor dit eksempel slår fejl, mens det i Lukas' svar virker. Den relevante forskel er, at Lukas indlejrede arrayet i et andet array-lag med array[d.a] .

Du falder over den forkerte antagelse, at du kunne erklære en type int[][] . Men du kan ikke:int[][] er den samme type som int[] til PostgreSQL-systemet. Kapitlet om arraytyper i manualen forklarer:

Den nuværende implementering håndhæver heller ikke det deklarerede antal dimensioner. Arrays af en bestemt elementtype anses alle for at være af samme type, uanset størrelse eller antal dimensioner. Så erklærer matrixstørrelsen eller antallet af dimensioner iCREATE TABLE er blot dokumentation; det påvirker ikke køretidsadfærd.

En n -dimensional heltalsarray er faktisk en matrix af n-1 -dimensionelle arrays af heltal i PostgreSQL. Du kan ikke se det fra typen, der kun definerer grundelementet . Du skal spørge array_dims() for at få detaljerne.

For at demonstrere:

SELECT array_agg_mult(arr1)               AS arr1  --> 1-dim array
     , array_agg_mult(ARRAY[arr1])        AS arr2  --> 2-dim array
     , array_agg_mult(ARRAY[ARRAY[arr1]]) AS arr3  --> 3-dim array
       -- etc.
FROM  (
   VALUES
      ('{1,2,3}'::int[])                           -- 1-dim array
    , ('{4,5,6}')
    , ('{7,8,9}')
   ) t(arr1);

Eller:

SELECT array_agg_mult(arr2)        AS arr2  --> 2-dim array
     , array_agg_mult(ARRAY[arr2]) AS arr3  --> 3-dim array
     , array_agg(arr2)             AS arr3  --> 3-dim array; superior in Postgres 9.5+
FROM  (
   VALUES
      ('{{1,2,3}}'::int[])                  -- 2-dim array
     ,('{{4,5,6}}')
     ,('{{7,8,9}}')
   ) t(arr2);

Alle resulterende kolonner er af samme type :int[] (selvom den indeholder et andet antal dimensioner).



  1. Spor signaler med en signalbehandlingsdatamodel

  2. mySQL-fejl 1040:For mange forbindelser

  3. SQL Server Database Server Hardware Upgrade Case Study

  4. JSON_SET() – Indsæt eller opdater værdier i et JSON-dokument i MySQL