Postgres 9.5 o versioni successive
... viene fornito con una variante aggiuntiva della funzione di aggregazione array_agg()
. Il manuale:
array di input concatenati in array di una dimensione superiore (gli input devono avere tutti la stessa dimensionalità e non possono essere vuoti o nulli)
Quindi non è esattamente la stessa della funzione di aggregazione personalizzata array_agg_mult()
sotto. Ma usalo, se puoi. È più veloce.
Correlati:
- Come ordinare un array int bidimensionale in PostgreSQL?
Postgres 9.4 o precedente
Funzione di aggregazione per qualsiasi tipo di matrice
Con il tipo polimorfico anyarray
funziona con tutti i tipi di array (incluso integer[]
):
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
Come fornito da @Lukas, la funzione personalizzata arrayappend()
non è necessario. Il built-in array_cat()
fa il lavoro. Tuttavia, questo non spiega il perché il tuo esempio fallisce, mentre quello nella risposta di Lukas funziona. La differenza rilevante è che Lukas ha nidificato l'array in un altro livello di array con array[d.a]
.
Inciampi nel presupposto errato che potresti dichiarare un tipo int[][]
. Ma non puoi:int[][]
è dello stesso tipo come int[]
per il sistema di tipo PostgreSQL. Il capitolo sui tipi di array nel manuale spiega:
Anche l'attuale implementazione non applica il numero dichiarato di dimensioni. Le matrici di un particolare tipo di elemento sono tutte considerate dello stesso tipo, indipendentemente dalle dimensioni o dal numero di dimensioni. Quindi, dichiarando la dimensione dell'array o il numero di dimensioni inCREATE TABLE
è semplicemente documentazione; non influisce sul comportamento in fase di esecuzione.
Un n
-dimensional intero array è effettivamente un array di n-1
matrici -dimensionali di interi in PostgreSQL. Non puoi dirlo dal tipo che definisce solo l'elemento di base . Devi chiedere array_dims()
per ottenere le specifiche.
Per dimostrare:
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);
Oppure:
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);
Tutti le colonne risultanti sono dello stesso tipo :int[]
(anche se contiene un numero diverso di dimensioni).