Postgres 9.5 nebo novější
... dodává se s další variantou agregační funkce array_agg()
. Manuál:
vstupní pole zřetězená do pole jedné vyšší dimenze (vstupy musí mít všechny stejnou dimenzi a nemohou být prázdné ani null)
Není tedy úplně stejná jako vlastní agregační funkce array_agg_mult()
níže. Ale použijte to, pokud můžete. Je to rychlejší.
Související:
- Jak třídit dvourozměrné pole int v PostgreSQL?
Postgres 9.4 nebo starší
Agregační funkce pro libovolné typ pole
S polymorfním typem anyarray
funguje pro všechny druhy polí (včetně integer[]
):
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
Jak uvedl @Lukas, vlastní funkce arrayappend()
není potřeba. Vestavěná funkce array_cat()
dělá práci. To však nevysvětluje proč váš příklad selže, zatímco ten v Lukasově odpovědi funguje. Relevantní rozdíl je v tom, že Lukas vnořil pole do jiné vrstvy pole pomocí array[d.a]
.
Zakopnete o nesprávný předpoklad, že byste mohli deklarovat typ int[][]
. Ale nemůžete:int[][]
je stejného typu jako int[]
pro systém typu PostgreSQL. Kapitola o typech polí v příručce vysvětluje:
Ani současná implementace nevynucuje deklarovaný počet dimenzí. Pole určitého typu prvku jsou všechna považována za stejný typ, bez ohledu na velikost nebo počet rozměrů. Takže deklarování velikosti pole nebo počtu rozměrů v
CREATE TABLE
je prostě dokumentace; neovlivňuje chování za běhu.
n
-dimenzionální celočíselné pole je efektivně pole n-1
-dimenzionální pole celých čísel v PostgreSQL. Z typu, který definuje pouze základní prvek, to nepoznáte . Musíte se zeptat array_dims()
abyste získali podrobnosti.
Pro demonstraci:
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);
Nebo:
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);
Vše výsledné sloupce jsou stejného typu :int[]
(i když obsahuje jiný počet dimenzí).