我有一个带有整数数组的表。

我想创建一个聚合函数,该函数将返回一个二维数组,其中所有行都在一起。然后将其传递给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()的其他变体。 The manual:



因此,与下面的自定义聚合函数array_agg_mult()不完全相同。但是,如果可以的话,请使用它。它更快。

有关的:

  • How to sort two dimensional int array in PostgreSQL?

  • Postgres 9.4或更旧

    任何数组类型的聚合函数

    使用polymorphic type anyarray ,它适用于所有类型的数组(包括integer[]):
    CREATE AGGREGATE array_agg_mult (anyarray) (
       SFUNC     = array_cat
     , STYPE     = anyarray
     , INITCOND  = '{}'
    );
    

    如@Lukas提供的那样,不需要自定义函数arrayappend()。内置的 array_cat() 可以完成这项工作。但是,这并不能解释您的示例为何失败,而卢卡斯的答案中的示例仍然有效。相关的区别是Lukas使用array[d.a]将数组嵌套到另一个数组层中。

    您可能会误认为可以声明int[][]类型。但是您不能:int[][]与PostgreSQL类型系统的int[]是类型相同的。 chapter on array types in the manual解释:


    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[](即使包含不同数量的维)。

    10-06 05:00
    查看更多