Postgres 9.5或更高版本
... 额外提供了一个变种的聚合函数array_agg()
。 手册:
将输入数组连接成一个更高维度的数组(输入必须具有相同的维度,并且不能是空或null)
因此,它与下面的自定义聚合函数array_agg_mult()
并不完全相同。但是如果可以使用它,它会更快。
相关:
Postgres 9.4或更早版本
任何数组类型的聚合函数
使用多态类型anyarray
可以适用于各种数组类型(包括integer[]
):
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
, STYPE = anyarray
, INITCOND = '{}'
);
如@Lukas所提供的,自定义函数
arrayappend()
是不需要的。内置函数
array_cat()
已经可以胜任了。然而,这并不能解释为什么你的示例失败了,而Lukas答案中的那个可以工作。相关的区别是Lukas用
array[d.a]
将数组嵌套到另一个数组层中。
你犯了一个错误的假设,认为你可以声明一个类型
int[][]
。但是你不能:对于PostgreSQL类型系统,
int[][]
与
int[]
是
相同的类型。
手册中关于数组类型的章节有解释:
当前的实现也不会强制执行所声明的维数。特定元素类型的数组都被认为是相同类型的,无论大小或维数如何。因此,在
CREATE TABLE
中声明数组大小或维数只是文档说明;它不影响运行时行为。
在PostgreSQL中,一个n维整数数组实际上是一个n-1维整数数组的数组。您无法从类型中看出这一点,因为类型只定义了基本元素。您必须使用
array_dims()
来获取具体信息。
为了演示:
SELECT array_agg_mult(arr1) AS arr1
, array_agg_mult(ARRAY[arr1]) AS arr2
, array_agg_mult(ARRAY[ARRAY[arr1]]) AS arr3
FROM (
VALUES
('{1,2,3}'::int[])
, ('{4,5,6}')
, ('{7,8,9}')
) t(arr1);
或者:
SELECT array_agg_mult(arr2) AS arr2
, array_agg_mult(ARRAY[arr2]) AS arr3
, array_agg(arr2) AS arr3
FROM (
VALUES
('{{1,2,3}}'::int[])
,('{{4,5,6}}')
,('{{7,8,9}}')
) t(arr2);
所有生成的列都是相同的类型:
int[]
(尽管包含不同数量的维度)。