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[]
(въпреки че съдържа различен брой измерения).