【问题标题】:appending to multi dimensional arrays in postgres附加到 postgres 中的多维数组
【发布时间】:2014-10-04 06:53:51
【问题描述】:

我正在尝试创建一个需要累积所有列值以供以后处理的多列聚合函数。

CREATE OR REPLACE FUNCTION accumulate_scores(prev integer[][],l1 integer,
l2 integer,l3 integer) RETURNS integer[][] AS
$$      
BEGIN  
prev[1] = array_append(prev[1],l1);
prev[2] = array_append(prev[2],l2);
prev[3] = array_append(prev[3],l3);
return prev;
END 
$$ LANGUAGE plpgsql;

CREATE AGGREGATE my_aggregate(integer,integer,integer)(
 SFUNC  = accumulate_scores,
 STYPE     = integer[][],
 INITCOND  = '{}'  
);

select accumulate_scores(ARRAY[1]|| ARRAY[[1],[1]],2,3,4);     

我收到此错误

ERROR: function array_append(integer, integer) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.

如何将这些值累积到多维数组中?

编辑:我尝试使用 array_cat 并得到相同的错误。认为 array_append 可能是正确的,因为 prev[1] 是一维数组

【问题讨论】:

  • 我认为是因为array_append以数组、元素为参数,而array_append(prev[1],l1)中的prev[1]不是数组而是值。
  • 我认为您需要将array_cat用于多维数组,请参阅postgresql.org/docs/9.3/static/arrays.html。你希望的最终结果是什么?

标签: arrays postgresql multidimensional-array aggregate-functions


【解决方案1】:

你的函数和聚合函数会像这样“工作”,但它只会创建一个一维数组:

CREATE OR REPLACE FUNCTION accumulate_scores(prev integer[][]
                                            ,l1 integer
                                            ,l2 integer
                                            ,l3 integer)
  RETURNS integer[][] AS
$func$
BEGIN 
prev := prev || ARRAY[l1,l2,l3];

RETURN prev;
END 
$func$ LANGUAGE plpgsql;

CREATE AGGREGATE my_aggregate(integer,integer,integer)(
 SFUNC     = accumulate_scores,
 STYPE     = integer[][],
 INITCOND  = '{}'  
);

声明RETURNS integer[][] 仅相当于RETURNS integer[]。对于 Postgres,同一基本元素上的所有数组都是 same 类型。额外的括号仅用于文档并被忽略。

要实际生成多维数组,您不需要自定义函数。只是一个自定义聚合函数:

CREATE AGGREGATE array_agg_mult (anyarray)  (
    SFUNC     = array_cat
   ,STYPE     = anyarray
   ,INITCOND  = '{}'
);

那么你可以:

SELECT array_agg_mult(ARRAY[ARRAY[l1,l2,l3]])  -- note the two array layers!
from   tbl;

更多细节在这里:

【讨论】:

  • 谢谢。我使用方法 2 来获取一个多维数组,我在聚合的最终函数中将其处理成多个单个数组,我可以在这些数组上进行进一步的数学运算
【解决方案2】:

这就是我对问题的理解

select array[
    array_agg(l1),
    array_agg(l2),
    array_agg(l3)
]
from (values
    (1, 9, 1, 2, 3), (2, 9, 4, 5, 6)
) s(id, bar, l1, l2, l3)
group by bar;
        array        
---------------------
 {{1,4},{2,5},{3,6}}

【讨论】:

  • 更像 CREATE TABLE foo(id bigserial NOT NULL, l1 integer, l2 integer, l3 integer); select my_aggregate(l1,l2,l3) from foo where blah blah group by bar
  • foo 有许多列,我省略了。其中任何一个都可能是 bar。
  • @Gokul 所以你需要 bar 作为数组的第一个元素吗?
  • 我只使用 bar 来选择我需要应用聚合函数的行组。
猜你喜欢
  • 2016-03-18
  • 2019-11-21
  • 2018-03-08
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-21
  • 1970-01-01
相关资源
最近更新 更多