Я не знаю, есть ли какой-нибудь более простой способ (я надеюсь, что так), но это работает (PostgreSQL не имеет массива массивов, поэтому array_agg
aproach здесь не работает):
CREATE OR REPLACE FUNCTION func()
RETURNS int[] AS $$
DECLARE
arr int[];
res int[];
n int;
BEGIN
res := '{{0, 0}}';
FOR arr IN SELECT t FROM tbl_foo
LOOP
res := res || arr;
END LOOP;
n := array_length(res, 1);
RETURN res[2:n];
END $$
LANGUAGE 'plpgsql';
Пример:
CREATE TABLE tbl_foo (id serial, t int[]);
INSERT INTO tbl_foo (t) VALUES
('{1, 2}'),
('{5, 2}'),
('{6, 2}'),
('{1, 7}'),
('{1, 8}'),
('{1, 9}');
SELECT func();
func
---------------------------------------
{{1,2},{5,2},{6,2},{1,7},{1,8},{1,9}}
(1 row)
EDIT:
Второе решение основано на новой агрегатной функции, которая называется, скажем, array2_agg
:
CREATE OR REPLACE FUNCTION array2_agg_cutFirst(res anyarray)
RETURNS anyarray AS $$
BEGIN
RETURN res[2:array_length(res, 1)];
END $$
LANGUAGE 'plpgsql';
CREATE AGGREGATE array2_agg(anyarray)
(
SFUNC = array_cat,
STYPE = anyarray,
FINALFUNC = array2_agg_cutFirst,
INITCOND = '{{0, 0}}'
);
SELECT array2_agg(t) FROM tbl_foo;
array2_agg
---------------------------------------
{{1,2},{5,2},{6,2},{1,7},{1,8},{1,9}}
(1 row)
Мне нужна эта array2_agg_cutFirst
функция (просто обрезка первого '{0, 0}'
подмассива), потому что INITCOND = '{{}}'
недопустим.