Postgres 9.5 или по-нова версия
... се доставя с допълнителен вариант на агрегатната функция array_agg() . Ръководството:
входни масиви, конкатенирани в масив с едно по-високо измерение (всички входове трябва да имат еднаква размерност и не могат да бъдат празни или нулеви)
Така че не е точно същото като персонализираната агрегатна функция array_agg_mult() По-долу. Но използвайте го, ако можете. По-бързо е.
Свързано:
- Как да сортирам двуизмерен int масив в PostgreSQL?
Postgres 9.4 или по-стара версия
Обобщаваща функция за всякак тип масив
С полиморфния тип anyarray работи за всички видове масиви (включително integer[] ):
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
Както @Lukas предостави, персонализираната функция arrayappend() не е необходимо. Вграденият array_cat() върши работата. Това обаче не обяснява защо вашият пример се проваля, докато този в отговора на Лукас работи. Съответната разлика е, че Лукас е вложил масива в друг слой масив с array[d.a] .
Препъвате се в неправилното предположение, че бихте могли да декларирате тип int[][] . Но не можете:int[][] е от същия тип като int[] за системата тип PostgreSQL. Главата за типовете масиви в ръководството обяснява:
Текущата реализация също не налага декларирания брой измерения. Масивите от конкретен тип елемент се считат за от един и същи тип, независимо от размера или броя на измеренията. И така, деклариране на размера на масива или броя на измеренията в
CREATE TABLEе просто документация; това не влияе на поведението по време на изпълнение.
n -дименсионалният целочислен масив ефективно е масив от n-1 -размерни масиви от цели числа в PostgreSQL. Не можете да разберете това от типа, който дефинира само базовия елемент . Трябва да попитате array_dims() за да получите подробности.
За демонстрация:
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);
Или:
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);
Всички получените колони са от същия тип :int[] (въпреки че съдържа различен брой измерения).