Postgres 9.5 或更新版本
... 附带聚合函数 array_agg() 的附加变体。 The manual:
输入数组连接成一维数组(输入
必须都具有相同的维度,并且不能为空或 null)
所以和下面的自定义聚合函数array_agg_mult()不完全一样。但是,如果可以的话,请使用它。它更快。
相关:
Postgres 9.4 或更早版本
any 数组类型的聚合函数
使用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 类型系统的int[] 是相同类型。 chapter on array types in the manual 解释说:
当前的实现不强制声明的数量
尺寸。特定元素类型的数组都是
被认为是同一类型,无论大小或数量
方面。因此,在中声明数组大小或维数
CREATE TABLE 只是文档;它不会影响运行时行为。
n 维整数数组实际上是 PostgreSQL 中n-1 维整数数组的数组。您无法从仅定义 基本元素的类型中看出这一点。详情请咨询array_dims()。
演示:
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);
或者:
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);
所有结果列都具有相同的类型:int[](即使包含不同数量的维度)。