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

Anfängliches Array in Funktion zum Aggregieren eines mehrdimensionalen Arrays

Postgres 9.5 oder neuer

... wird mit einer zusätzlichen Variante der Aggregatfunktion array_agg() ausgeliefert . Das Handbuch:

Eingabearrays, die zu einem Array einer höheren Dimension verkettet sind (Eingaben müssen alle dieselbe Dimensionalität haben und dürfen nicht leer oder null sein)

Also nicht genau dasselbe wie die benutzerdefinierte Aggregatfunktion array_agg_mult() unter. Aber nutze es, wenn du kannst. Es ist schneller.

Verwandte:

  • Wie sortiert man ein zweidimensionales Int-Array in PostgreSQL?

Postgres 9.4 oder älter

Aggregatfunktion für alle Array-Typ

Mit dem polymorphen Typ anyarray es funktioniert für alle Arten von Arrays (einschließlich integer[] ):

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

Wie von @Lukas bereitgestellt, die benutzerdefinierte Funktion arrayappend() wird nicht gebraucht. Das eingebaute array_cat() macht den Job. Das erklärt jedoch nicht warum Ihr Beispiel schlägt fehl, während das in Lukas 'Antwort funktioniert. Der relevante Unterschied besteht darin, dass Lukas das Array mit array[d.a] in eine andere Array-Schicht verschachtelt hat .

Sie stolpern über die falsche Annahme, dass Sie einen Typ int[][] deklarieren könnten . Aber Sie können nicht:int[][] ist derselbe Typ als int[] für das PostgreSQL-Typsystem. Das Kapitel über Array-Typen im Handbuch erklärt:

Die aktuelle Implementierung erzwingt auch nicht die deklarierte Anzahl von Dimensionen. Arrays eines bestimmten Elementtyps werden unabhängig von Größe oder Anzahl der Dimensionen alle als vom gleichen Typ betrachtet. Deklarieren Sie also die Arraygröße oder die Anzahl der Dimensionen in CREATE TABLE ist einfach Dokumentation; es wirkt sich nicht auf das Laufzeitverhalten aus.

Ein n -dimensionales ganzzahliges Array ist effektiv ein Array von n-1 -dimensionale Integer-Arrays in PostgreSQL. Das erkennt man nicht am Typ, der nur das Basiselement definiert . Sie müssen array_dims() fragen um Einzelheiten zu erfahren.

Zur Demonstration:

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

Oder:

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 resultierende Spalten sind vom selben Typ :int[] (auch wenn sie eine andere Anzahl von Dimensionen enthält).