Postgres 9.5 ou posterior
tem
array_agg(array expression)
:
array_agg
(anyarray
) →anyarray
Concatena todos os arrays de entrada em um array de uma dimensão superior. (As entradas devem ter todas a mesma dimensionalidade e não podem ser vazias ou nulas.)
Este é um substituto para minha função agregada personalizada
array_agg_mult()
demonstrado abaixo. É implementado em C e consideravelmente mais rápido. Use-o. Postgres 9.4
Use o
ROWS FROM
construct ou o unnest()
atualizado que leva vários arrays para desaninhar em paralelo. Cada um pode ter um comprimento diferente. Você obtém (por documentação):
[...] o número de linhas de resultado neste caso é o do maior resultado da função, com resultados menores preenchidos com valores nulos para corresponder.
Use esta variante mais limpa e simples:
SELECT ARRAY[a,b] AS ab
FROM unnest('{a,b,c}'::text[]
, '{d,e,f}'::text[]) x(a,b);
Postgres 9.3 ou anterior
Zip simples()
Considere a seguinte demonstração do Postgres 9.3 ou anterior :
SELECT ARRAY[a,b] AS ab
FROM (
SELECT unnest('{a,b,c}'::text[]) AS a
, unnest('{d,e,f}'::text[]) AS b
) x;
Resultado:
ab
-------
{a,d}
{b,e}
{c,f}
Observe que ambas as matrizes devem ter o mesmo número de elementos para desaninhar em paralelo ou, em vez disso, você obtém uma junção cruzada.
Você pode envolver isso em uma função, se quiser:
CREATE OR REPLACE FUNCTION zip(anyarray, anyarray)
RETURNS SETOF anyarray LANGUAGE SQL AS
$func$
SELECT ARRAY[a,b] FROM (SELECT unnest($1) AS a, unnest($2) AS b) x;
$func$;
Ligar:
SELECT zip('{a,b,c}'::text[],'{d,e,f}'::text[]);
Mesmo resultado.
zip() para array multidimensional:
Agora, se você deseja agregar esse novo conjunto de matrizes em um bidimensional array, fica mais complicado.
SELECT ARRAY (SELECT ...)
ou:
SELECT array_agg(ARRAY[a,b]) AS ab
FROM (
SELECT unnest('{a,b,c}'::text[]) AS a
,unnest('{d,e,f}'::text[]) AS b
) x
ou:
SELECT array_agg(ARRAY[ARRAY[a,b]]) AS ab
FROM ...
todos resultarão na mesma mensagem de erro (testado com a página 9.1.5):
ERRO:não foi possível encontrar o tipo de matriz para o tipo de dados text[]
Mas há uma maneira de contornar isso, pois trabalhamos nesta questão intimamente relacionada.
Crie uma função de agregação personalizada:
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
E use assim:
SELECT array_agg_mult(ARRAY[ARRAY[a,b]]) AS ab
FROM (
SELECT unnest('{a,b,c}'::text[]) AS a
, unnest('{d,e,f}'::text[]) AS b
) x
Resultado:
{{a,d},{b,e},{c,f}}
Observe o
ARRAY[]
adicional camada! Sem ele e apenas:SELECT array_agg_mult(ARRAY[a,b]) AS ab
FROM ...
Você obtém:
{a,d,b,e,c,f}
O que pode ser útil para outros fins.
Role outra função:
CREATE OR REPLACE FUNCTION zip2(anyarray, anyarray)
RETURNS SETOF anyarray LANGUAGE SQL AS
$func$
SELECT array_agg_mult(ARRAY[ARRAY[a,b]])
FROM (SELECT unnest($1) AS a, unnest($2) AS b) x;
$func$;
Ligar:
SELECT zip2('{a,b,c}'::text[],'{d,e,f}'::text[]); -- or any other array type
Resultado:
{{a,d},{b,e},{c,f}}