Postgres 9.5 nebo novější
má array_agg(array expression)
:
array_agg
(anyarray
) →anyarray
Zřetězí všechna vstupní pole do pole jedné vyšší dimenze. (Všechny vstupy musí mít stejnou dimenzi a nemohou být prázdné ani null.)
Toto je náhrada za moji vlastní agregační funkci array_agg_mult()
ukázáno níže. Je implementován v C a podstatně rychlejší. Použijte to.
Postgres 9.4
Použijte ROWS FROM
konstrukt nebo aktualizovaný unnest()
což vyžaduje paralelní rozpojení více polí. Každá může mít jinou délku. Získáte (podle dokumentace):
[...] počet řádků výsledků je v tomto případě počet řádků s největší funkcí, s menšími výsledky doplněnými hodnotami null, aby odpovídaly.
Použijte tuto čistší a jednodušší variantu:
SELECT ARRAY[a,b] AS ab
FROM unnest('{a,b,c}'::text[]
, '{d,e,f}'::text[]) x(a,b);
Postgres 9.3 nebo starší
Jednoduché zip()
Zvažte následující demo pro Postgres 9.3 nebo starší :
SELECT ARRAY[a,b] AS ab
FROM (
SELECT unnest('{a,b,c}'::text[]) AS a
, unnest('{d,e,f}'::text[]) AS b
) x;
Výsledek:
ab
-------
{a,d}
{b,e}
{c,f}
Všimněte si, že obě pole musí mít stejný počet prvků rozpojit paralelně, nebo místo toho získáte křížové spojení.
Můžete to zabalit do funkce, pokud chcete:
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$;
Volejte:
SELECT zip('{a,b,c}'::text[],'{d,e,f}'::text[]);
Stejný výsledek.
zip() do vícerozměrného pole:
Nyní, pokud chcete agregovat tuto novou sadu polí do jednoho dvourozměrného pole, bude to složitější.
SELECT ARRAY (SELECT ...)
nebo:
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
nebo:
SELECT array_agg(ARRAY[ARRAY[a,b]]) AS ab
FROM ...
všechny budou mít za následek stejnou chybovou zprávu (testováno na str. 9.1.5):
CHYBA:Nelze najít typ pole pro datový typ text[]
Ale existuje způsob, jak to obejít, jak jsme se dopracovali k této úzce související otázce.
Vytvořte vlastní agregační funkci:
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
A použijte to takto:
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
Výsledek:
{{a,d},{b,e},{c,f}}
Všimněte si dalšího ARRAY[]
vrstva! Bez něj a jen:
SELECT array_agg_mult(ARRAY[a,b]) AS ab
FROM ...
Získáte:
{a,d,b,e,c,f}
Což může být užitečné pro jiné účely.
Roll další funkce:
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$;
Volejte:
SELECT zip2('{a,b,c}'::text[],'{d,e,f}'::text[]); -- or any other array type
Výsledek:
{{a,d},{b,e},{c,f}}