Postgres 9,5 или новее
... поставляется с дополнительным вариантом агрегатной функции array_agg()
, которая может агрегировать массивы в массив следующего более высокого измерения. См:
Служит заменой настраиваемой функции агрегирования array_agg_mult()
ниже.
Postgres 9,4 или старше
Агрегатная функция для любого типа массива
С полиморфным типом anyarray
он работает для всех видов массивов (включая integer[]
):
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
Как и в @Lukas, пользовательская функция arrayappend()
не нужна. Встроенный array_cat()
делает свою работу. Однако это не объясняет , почему ваш пример терпит неудачу, в то время как тот, что в ответе @Lukas, работает. Отличие заключается в том, что @Lukas вложил массив в другой слой массива с array[d.a]
.
Вы ошибаетесь в предположении, что вы можете объявить тип int[][]
. Но вы не можете: int[][]
- это того же типа , что и int[]
для системы типов PostgreSQL. Глава о типах массивов в руководстве объясняет:
Текущая реализация не обеспечивает заявленное количество
Размеры тоже. Массивы определенного типа элемента все
считается того же типа, независимо от размера или количества
размеры. Итак, объявляя размер массива или количество измерений в
CREATE TABLE
это просто документация; это не влияет на поведение во время выполнения.
n
-мерный целочисленный массив - это массив n-1
-мерных массивов целых чисел в PostgreSQL. Вы не можете отличить это от типа, который определяет только базовый элемент . Вы должны попросить array_dims()
, чтобы получить подробности.
Для демонстрации:
SELECT array_agg_mult(arr1) AS arr2 --> 2-dimensional array
, array_agg_mult(ARRAY[arr1]) AS arr3 --> 3-dimensional array
, array_agg_mult(ARRAY[ARRAY[arr1]]) AS arr4 --> 4-dimensional array
-- etc.
FROM (
VALUES
('{1,2,3}'::int[]) -- = 1-dimensional array
, ('{4,5,6}')
, ('{7,8,9}')
) t(arr1);
Или:
SELECT array_agg(arr2) AS arr3 --> 3-dimensional array
FROM (
VALUES
('{{1,2,3}}'::int[]) -- = 2-dimensional array
,('{{4,5,6}}')
,('{{7,8,9}}')
) t(arr2);
Все результирующие столбцы имеют одинаковый тип : int[]
(хотя и содержат другое количество измерений).