Postgres 9.5 lub nowszy
ma array_agg(array expression)
:
array_agg
( anyarray
) → anyarray
Łączy wszystkie tablice wejściowe w tablicę o jednym wyższym wymiarze. (Wszystkie dane wejściowe muszą mieć tę samą wymiarowość i nie mogą być puste ani puste).
To jest zamiennik dla mojej niestandardowej funkcji agregującej array_agg_mult()
pokazane poniżej. Jest zaimplementowany w C i znacznie szybszy. Użyj go.
Postgres 9.4
Użyj ROWS FROM
konstrukcja lub zaktualizowana unnest()
co wymaga równoległego rozgniecenia wielu tablic. Każdy może mieć inną długość. Otrzymujesz (zgodnie z dokumentacją):
[...] liczba wierszy wyników w tym przypadku odpowiada największemu wynikowi funkcji, z mniejszymi wynikami uzupełnionymi wartościami null do dopasowania.
Użyj tego czystszego i prostszego wariantu:
SELECT ARRAY[a,b] AS ab
FROM unnest('{a,b,c}'::text[]
, '{d,e,f}'::text[]) x(a,b);
Postgres 9.3 lub starszy
Prosty zip()
Rozważ następujące demo Postgresa 9.3 lub starszego :
SELECT ARRAY[a,b] AS ab
FROM (
SELECT unnest('{a,b,c}'::text[]) AS a
, unnest('{d,e,f}'::text[]) AS b
) x;
Wynik:
ab
-------
{a,d}
{b,e}
{c,f}
Pamiętaj, że obie tablice muszą mieć tę samą liczbę elementów rozpakować równolegle lub zamiast tego otrzymasz sprzężenie krzyżowe.
Możesz zapakować to w funkcję, jeśli chcesz:
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$;
Zadzwoń:
SELECT zip('{a,b,c}'::text[],'{d,e,f}'::text[]);
Ten sam wynik.
zip() do tablicy wielowymiarowej:
Teraz, jeśli chcesz agregować ten nowy zestaw tablic w jeden 2-wymiarowy tablica, robi się bardziej skomplikowana.
SELECT ARRAY (SELECT ...)
lub:
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
lub:
SELECT array_agg(ARRAY[ARRAY[a,b]]) AS ab
FROM ...
wszystkie spowodują ten sam komunikat o błędzie (testowane na stronie 9.1.5):
BŁĄD:nie można znaleźć typu tablicy dla typu danych text[]
Istnieje jednak sposób na obejście tego, ponieważ opracowaliśmy to w ramach tego ściśle powiązanego pytania.
Utwórz niestandardową funkcję agregującą:
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
I użyj go w ten sposób:
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
Wynik:
{{a,d},{b,e},{c,f}}
Zwróć uwagę na dodatkowy ARRAY[]
warstwa! Bez tego i po prostu:
SELECT array_agg_mult(ARRAY[a,b]) AS ab
FROM ...
Otrzymujesz:
{a,d,b,e,c,f}
Które mogą być przydatne do innych celów.
Rzuć inną funkcję:
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$;
Zadzwoń:
SELECT zip2('{a,b,c}'::text[],'{d,e,f}'::text[]); -- or any other array type
Wynik:
{{a,d},{b,e},{c,f}}