Postgres 9.5 lub nowszy
... dostarczany z dodatkowym wariantem funkcji agregującej array_agg()
. Instrukcja:
tablice wejściowe połączone w tablice o jednym wyższym wymiarze (wszystkie dane wejściowe muszą mieć tę samą wymiarowość i nie mogą być puste ani puste)
A więc nie dokładnie to samo, co niestandardowa funkcja agregująca array_agg_mult()
poniżej. Ale użyj go, jeśli możesz. Jest szybszy.
Powiązane:
- Jak posortować dwuwymiarową tablicę int w PostgreSQL?
Postgres 9.4 lub starszy
Funkcja agregująca dla dowolnych typ tablicy
Z typem polimorficznym anyarray
działa dla wszystkich rodzajów tablic (w tym integer[]
):
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
Jak podał @Lukas, niestandardowa funkcja arrayappend()
nie jest potrzebne. Wbudowana funkcja array_cat()
wykonuje pracę. Nie wyjaśnia to jednak, dlaczego Twój przykład zawodzi, podczas gdy ten w odpowiedzi Lukasa działa. Istotna różnica polega na tym, że Lukas zagnieździł tablicę w innej warstwie tablicy za pomocą array[d.a]
.
Potykasz się o błędne założenie, że możesz zadeklarować typ int[][]
. Ale nie możesz:int[][]
jest tego samego typu jako int[]
dla systemu typu PostgreSQL. Rozdział na temat typów tablic w podręczniku wyjaśnia:
Obecna implementacja również nie wymusza zadeklarowanej liczby wymiarów. Uznaje się, że tablice określonego typu elementu są tego samego typu, niezależnie od rozmiaru lub liczby wymiarów. Tak więc deklarowanie rozmiaru tablicy lub liczby wymiarów w CREATE TABLE
to po prostu dokumentacja; nie wpływa na zachowanie w czasie wykonywania.
n
-wymiarowa tablica liczb całkowitych w rzeczywistości jest tablicą n-1
-wymiarowe tablice liczb całkowitych w PostgreSQL. Nie można tego odróżnić od typu, który definiuje tylko element podstawowy . Musisz zapytać array_dims()
aby poznać szczegóły.
Aby zademonstrować:
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);
Lub:
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);
Wszystkie wynikowe kolumny są tego samego typu :int[]
(chociaż zawiera inną liczbę wymiarów).