我有一个包含整数数组的表。
我想创建一个聚合函数,它将返回一个包含所有行的二维数组。然后它被传递给plr
以对其进行一些数学运算。
我有:
CREATE OR REPLACE
FUNCTION arrayappend(left int[][], right int[])
RETURNS int[] AS
$BODY$
SELECT $1 || $2 ;
$BODY$
LANGUAGE SQL;
和
CREATE AGGREGATE array_sum2 (int[]) (
SFUNC = arrayappend,
STYPE = int[][],
INITCOND = '{}'
);
但是返回类型是int[]
,而不是int[][]
?
如何使用空的二维整数数组初始化聚合?
答案 0 :(得分:9)
...附带了聚合函数array_agg()
的其他变体,可以将数组聚合到下一个更高维的数组中。参见:
它可以作为下面自定义聚合函数array_agg_mult()
的替代品。
使用polymorphic type anyarray
它适用于所有类型的数组(包括integer[]
):
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
正如@Lukas所提供的,不需要自定义函数arrayappend()
。内置的array_cat()
完成了这项工作。但是,这并没有解释为什么你的例子失败了,而@Lukas的答案中的那个失败了。相关的区别是@Lukas将数组嵌套到另一个数组array[d.a]
。
您错过了可以声明类型int[][]
的错误假设。但你不能:int[][]
与PostgreSQL类型系统的{strong>相同类型为int[]
。 chapter on array types in the manual解释说:
当前实现不强制声明的数量 尺寸要么。特定元素类型的数组都是 被认为属于同一类型,无论大小或数量 尺寸。因此,声明数组的大小或维数
CREATE TABLE
只是文档;它不会影响运行时行为。
n
维整数数组实际上是PostgreSQL中n-1
维整数数组的数组。您无法从仅定义基本元素的类型中分辨出来。您必须要求array_dims()
获取具体信息。
演示:
SELECT array_agg_mult(arr1) AS arr2 --> 2-dimensional array
, array_agg_mult(ARRAY[arr1]) AS arr3 --> 3-dimensional array
, array_agg_mult(ARRAY[ARRAY[arr1]]) AS arr4 --> 4-dimensional array
-- etc.
FROM (
VALUES
('{1,2,3}'::int[]) -- = 1-dimensional array
, ('{4,5,6}')
, ('{7,8,9}')
) t(arr1);
或者:
SELECT array_agg(arr2) AS arr3 --> 3-dimensional array
FROM (
VALUES
('{{1,2,3}}'::int[]) -- = 2-dimensional array
,('{{4,5,6}}')
,('{{7,8,9}}')
) t(arr2);
所有结果列具有相同的类型:int[]
(即使包含不同数量的维度)。
答案 1 :(得分:2)
使用内置的array_cat函数有效。
CREATE AGGREGATE array_sum2 (int[]) (
SFUNC = array_cat,
STYPE = int[],
INITCOND = '{}'
);
试验:
select array_sum2(array[d.a]) from (select array[1,1,2,3] as a union select array[5,8,13,21] as a) d;
array_sum2
-------------------------
{{1,1,2,3},{5,8,13,21}}