Postgres 9.5 ou mais recente
... vem com uma variante adicional da função agregada
array_agg()
. O manual:
arrays de entrada concatenados em array de uma dimensão superior (os inputs devem ter a mesma dimensionalidade e não podem ser vazios ou nulos)
Portanto, não é exatamente o mesmo que a função de agregação personalizada
array_agg_mult()
abaixo de. Mas use-o, se puder. É mais rápido. Relacionado:
- Como classificar array int bidimensional no PostgreSQL?
Postgres 9.4 ou anterior
Função agregada para qualquer tipo de matriz
Com o tipo polimórfico
anyarray
funciona para todos os tipos de arrays (incluindo integer[]
):CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
Conforme fornecido pelo @Lukas, a função personalizada
arrayappend()
Não é necessário. O array_cat()
embutido faz o trabalho. No entanto, isso não explica por que seu exemplo falha, enquanto o da resposta de Lukas funciona. A diferença relevante é que Lukas aninhou o array em outra camada de array com array[d.a]
. Você tropeça na suposição incorreta de que poderia declarar um tipo
int[][]
. Mas você não pode:int[][]
é do mesmo tipo como int[]
para o sistema de tipos PostgreSQL. O capítulo sobre tipos de array no manual explica:
A implementação atual também não impõe o número declarado de dimensões. Arrays de um determinado tipo de elemento são todos considerados do mesmo tipo, independente do tamanho ou número de dimensões. Então, declarando o tamanho do array ou o número de dimensões emCREATE TABLE
é simplesmente documentação; ele não afeta o comportamento em tempo de execução.
Um
n
array inteiro dimensional efetivamente é um array de n-1
arrays dimensionais de inteiros no PostgreSQL. Você não pode dizer isso a partir do tipo que define apenas o elemento base . Você tem que perguntar array_dims()
para obter os detalhes. Para demonstrar:
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);
Ou:
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);
Todos as colunas resultantes são do mesmo tipo :
int[]
(mesmo contendo um número diferente de dimensões).