【问题标题】:Postgres GROUP BY integer arraysPostgres GROUP BY 整数数组
【发布时间】:2014-09-28 15:38:33
【问题描述】:

我在 Postgres 9.3 中的数据库表

| f1|f2 | f3
| 1 | 2 | {1,2,3}
| 1 | 3 | {4,5}

f1,f2 是整数 f3 是整数[]。

我怎样才能得到这个:

SELECT f1, myfn(f3)
FROM dbTable
GROUP BY f1;

所以我得到:

| 1 | {1,2,3,4,5}

Postgres中是否有类似array_agg这样的函数,可以连接数组并创建一个新数组;

【问题讨论】:

    标签: arrays postgresql aggregate-functions


    【解决方案1】:

    SQL Fiddle

    首先unnest 然后聚合

    select f1, array_agg(f3) as f3
    from (
        select f1, unnest(f3) as f3
        from dbtable
    ) s
    group by f1
    

    为了避免重复和排序输出(必须安装 intarry 扩展):

    select f1, sort(uniq(array_agg(f3))) as f3
    from (
        select f1, unnest(f3) as f3
        from dbtable
    ) s
    group by f1
    

    【讨论】:

    • +1 我看了stackoverflow.com/questions/7020264/…后也是这么想的。我希望有更高效的东西(我的 dbTable 没那么简单)
    • @Alexandros 可以创建自己的聚合函数,它会简化代码,但我不知道它是否会更高效。代码简洁是您所追求的吗?
    • 简单性并不是什么大问题(除非我们谈论的是 1000 行函数)。我更关心性能,但您的解决方案非常有效。如果您不介意,我会等几个小时再接受您的回答,以防有人提出惊人的建议(我对此表示怀疑)。希望没问题
    • 虽然看起来很奇怪,但这种解决方案似乎比聚合函数(虽然实现起来更简单)更好(并且更灵活,因为您可以对未嵌套的数组元素执行其他操作)。所以,两者都是很好的答案。
    【解决方案2】:

    我认为没有a built-in aggregate function,但您可以轻松创建自己的。

    查看the array functions and operators available,你想要的函数是array_cat - 运算符|| 通常更方便,但我们需要一个函数来创建聚合,否则必须将其包装在一个中。

    由于我们已经有了要使用的函数,我们可以基于它创建一个非常简单的聚合 - 从一个空数组开始,依次连接每个新项目,不需要特殊的中间数据或最后的步骤。

    CREATE AGGREGATE statement 如下(注意使用the anyarray pseudo-type 作为聚合的输入和输出):

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

    这应该可以让你准确地写出你想要的:

    SELECT f1, array_cat_agg(f3)
    FROM dbTable
    GROUP BY f1;
    

    Here's a demo of this in action on SQLFiddle.

    【讨论】:

    • +1 您的出色方法也很有效。我将测试这两个答案的性能并会回来。一个想法虽然。如果我只对整数数组感兴趣,会在函数定义上设置它,提高性能吗?你觉得怎么样。谢谢!!!
    • @Alexandros 聚合和函数的实际类型是在解析语句时确定的,而不是在运行时确定的,所以我怀疑将类型声明为 int[] 会带来任何性能优势的anyarray。即在我们的示例中,解析器“知道”f3 的类型为int[],因此将array_cat_agg 的参数和状态类型中的anyarray 标记解析为表示int[],对于参数和array_cat 本身的返回类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 2011-09-08
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    相关资源
    最近更新 更多