我想创建一个聚合函数,它将返回一个包含所有行的二维数组.然后它被传递给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 [] []?
如何使用空的二维整数数组初始化聚合?
Postgres 9.5或更新版本…附带了聚合函数array_agg()的其他变体,它可以将数组聚合到下一个更高维的数组中.看到:
> How to sort two dimensional int array in PostgreSQL?
它作为下面的自定义聚合函数array_agg_mult()的替代品.
Postgres 9.4或更高版本
任何数组类型的聚合函数
使用polymorphic type anyarray
它适用于所有类型的数组(包括integer []):
CREATE AGGREGATE array_agg_mult (anyarray) ( SFUNC = array_cat , STYPE = anyarray , INITCOND = '{}' );
正如@Lukas提供的那样,不需要自定义函数arrayappend().内置的array_cat()
完成了这项工作.但是,这并不能解释为什么你的例子失败了,而@Lukas的回答中的那个失败了.相关的区别是@Lukas将数组嵌套到另一个数组[d.a]的数组层.
你错过了一个错误的假设,你可以声明一个int [] []类型.但你不能:int [] []与PostgreSQL类型系统的int []类型相同. chapter on array types in the manual解释说:
The current implementation does not enforce the declared number of
dimensions either. Arrays of a particular element type are all
considered to be of the same type, regardless of size or number of
dimensions. So, declaring the array size or number of dimensions in
CREATE TABLE
is simply documentation; it does not affect run-time behavior.
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 [](即使包含不同数量的维度).