sql >> Databasteknik >  >> RDS >> PostgreSQL

Initial array i funktion för att aggregera flerdimensionell array

Postgres 9.5 eller senare

... levereras med en extra variant av aggregatfunktionen array_agg() . Manualen:

indatamatriser sammanlänkade till matriser med en högre dimension (indata måste alla ha samma dimensionalitet och får inte vara tomma eller noll)

Så inte exakt samma som den anpassade aggregatfunktionen array_agg_mult() Nedan. Men använd den om du kan. Det är snabbare.

Relaterat:

  • Hur sorterar man tvådimensionell int-array i PostgreSQL?

Postgres 9.4 eller äldre

Aggregeringsfunktion för alla matristyp

Med den polymorfa typen anyarray det fungerar för alla typer av arrayer (inklusive integer[] ):

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

Som @Lukas angav, den anpassade funktionen arrayappend() behövs inte. Den inbyggda array_cat() gör jobbet. Det förklarar dock inte varför ditt exempel misslyckas, medan det i Lukas svar fungerar. Den relevanta skillnaden är att Lukas kapslade arrayen i ett annat arraylager med array[d.a] .

Du snubblar över det felaktiga antagandet att du kan deklarera en typ int[][] . Men du kan inte:int[][] är av samma typ som int[] för systemet av typen PostgreSQL. Kapitlet om arraytyper i manualen förklarar:

Den nuvarande implementeringen upprätthåller inte heller det deklarerade antalet dimensioner. Matriser av en viss elementtyp anses alla vara av samma typ, oavsett storlek eller antal dimensioner. Så, deklarera matrisstorleken eller antalet dimensioner iCREATE TABLE är helt enkelt dokumentation; det påverkar inte körningsbeteendet.

Ett n -dimensionell heltalsmatris är faktiskt en matris med n-1 -dimensionella arrayer av heltal i PostgreSQL. Du kan inte se det från typen som bara definierar baselementet . Du måste fråga array_dims() för att få detaljerna.

För att demonstrera:

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

Alla resulterande kolumner är av samma typ :int[] (även om den innehåller ett annat antal dimensioner).



  1. Ta bort ett databaspostkonto från en profil (SSMS)

  2. TAN() Exempel i SQL Server

  3. Hur man får alla tabeller som har en primär nyckelbegränsning skapad i SQL Server Database - SQL Server / TSQL Tutorial 57

  4. Rekommenderat sätt / beställning att läsa data från en webbtjänst, analysera den data och infoga den i en SQLite db