Postgres 9.5 oder höher
hat array_agg(array expression)
:
array_agg
( anyarray
) → anyarray
Verkettet alle Eingabearrays zu einem Array mit einer höheren Dimension. (Die Eingaben müssen alle die gleiche Dimensionalität haben und dürfen nicht leer oder null sein.)
Dies ist ein Drop-in-Ersatz für meine benutzerdefinierte Aggregatfunktion array_agg_mult()
unten demonstriert. Es ist in C implementiert und erheblich schneller. Verwenden Sie es.
Postgres 9.4
Verwenden Sie die ROWS FROM
Konstrukt oder das aktualisierte unnest()
wodurch mehrere Arrays parallel entschachtelt werden müssen. Jeder kann eine andere Länge haben. Sie erhalten (per Dokumentation):
[...] die Anzahl der Ergebniszeilen ist in diesem Fall die des größten Funktionsergebnisses, wobei kleinere Ergebnisse passend mit Nullwerten aufgefüllt werden.
Verwenden Sie diese sauberere und einfachere Variante:
SELECT ARRAY[a,b] AS ab
FROM unnest('{a,b,c}'::text[]
, '{d,e,f}'::text[]) x(a,b);
Postgres 9.3 oder älter
Einfach zip()
Betrachten Sie die folgende Demo für Postgres 9.3 oder früher :
SELECT ARRAY[a,b] AS ab
FROM (
SELECT unnest('{a,b,c}'::text[]) AS a
, unnest('{d,e,f}'::text[]) AS b
) x;
Ergebnis:
ab
-------
{a,d}
{b,e}
{c,f}
Beachten Sie, dass beide Arrays die gleiche Anzahl von Elementen haben müssen parallel zu entschachteln, oder Sie erhalten stattdessen einen Cross Join.
Sie können dies in eine Funktion packen, wenn Sie möchten:
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$;
Aufruf:
SELECT zip('{a,b,c}'::text[],'{d,e,f}'::text[]);
Gleiches Ergebnis.
zip() in mehrdimensionales Array:
Nun, wenn Sie aggregieren möchten diesen neuen Satz von Arrays in ein zweidimensionales -Array, wird es komplizierter.
SELECT ARRAY (SELECT ...)
oder:
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
oder:
SELECT array_agg(ARRAY[ARRAY[a,b]]) AS ab
FROM ...
führen alle zu derselben Fehlermeldung (getestet mit Seite 9.1.5):
FEHLER:Arraytyp für Datentyp text[]
konnte nicht gefunden werden
Aber es gibt einen Weg, dies zu umgehen, wie wir unter dieser eng verwandten Frage ausgearbeitet haben.
Erstellen Sie eine benutzerdefinierte Aggregatfunktion:
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
Und verwenden Sie es so:
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
Ergebnis:
{{a,d},{b,e},{c,f}}
Beachten Sie das zusätzliche ARRAY[]
Schicht! Ohne sie und nur:
SELECT array_agg_mult(ARRAY[a,b]) AS ab
FROM ...
Sie erhalten:
{a,d,b,e,c,f}
Was für andere Zwecke nützlich sein kann.
Rollen Sie eine andere Funktion:
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$;
Aufruf:
SELECT zip2('{a,b,c}'::text[],'{d,e,f}'::text[]); -- or any other array type
Ergebnis:
{{a,d},{b,e},{c,f}}