Postgres 9.5 of nieuwer
... wordt geleverd met een extra variant van de aggregatiefunctie array_agg()
. De handleiding:
invoerarrays samengevoegd tot een array met een hogere dimensie (invoeren moeten allemaal dezelfde dimensionaliteit hebben en mogen niet leeg of null zijn)
Dus niet precies hetzelfde als de aangepaste aggregatiefunctie array_agg_mult()
onderstaand. Maar gebruik het, als je kunt. Het is sneller.
Gerelateerd:
- Hoe sorteer ik een tweedimensionale int-array in PostgreSQL?
Postgres 9.4 of ouder
Aggregatiefunctie voor elke matrixtype
Met het polymorfe type anyarray
het werkt voor alle soorten arrays (inclusief integer[]
):
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
Zoals @Lukas aangaf, is de aangepaste functie arrayappend()
is niet nodig. De ingebouwde array_cat()
doet het werk. Dat verklaart echter niet waarom jouw voorbeeld faalt, terwijl dat in het antwoord van Lukas werkt. Het relevante verschil is dat Lukas de array in een andere arraylaag heeft genest met array[d.a]
.
Je struikelt over de onjuiste veronderstelling dat je een type int[][]
. zou kunnen declareren . Maar je kunt niet:int[][]
is van hetzelfde type als int[]
voor het PostgreSQL-type systeem. In het hoofdstuk over arraytypes in de handleiding wordt uitgelegd:
De huidige implementatie dwingt het gedeclareerde aantal dimensies ook niet af. Arrays van een bepaald elementtype worden allemaal als van hetzelfde type beschouwd, ongeacht de grootte of het aantal dimensies. Dus, de arraygrootte of het aantal dimensies aangeven inCREATE TABLE
is gewoon documentatie; het heeft geen invloed op het runtime-gedrag.
Een n
-dimensionale integer-array is in feite een array van n-1
-dimensionale arrays van integer in PostgreSQL. Dat kun je niet zien aan het type dat alleen het basiselement definieert . Je moet array_dims()
. vragen om de details te krijgen.
Om te demonstreren:
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);
Of:
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 kolommen zijn van hetzelfde type :int[]
(ook al bevat het een ander aantal dimensies).