【问题标题】:array_agg for Array Types数组类型的array_agg
【发布时间】:2011-10-10 13:39:35
【问题描述】:

我正在尝试让array_agg 在 Postgresql 中使用数组类型,但我无法确定这是否可行,如果可行,该怎么做。我的查询的相关部分如下所示:

array_agg(ARRAY[e.alert_type::text, e.id::text, cast(extract(epoch from e.date_happened) as text)] order by e.date_happened asc, e.id asc)

我收到的错误回复是ERROR: could not find array type for data type text[]

这可能吗,还是我应该尝试另一种方法?

谢谢!

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    您可以编写自定义聚合来处理您的特定数组数组,例如:

    DROP TABLE IF EXISTS e;
    CREATE TABLE e
    (
        id serial PRIMARY KEY,
        alert_type text,
        date_happened timestamp with time zone
    );
    
    INSERT INTO e(alert_type, date_happened) VALUES
        ('red', '2011-05-10 10:15:06'),
        ('yellow', '2011-06-22 20:01:19');
    
    CREATE OR REPLACE FUNCTION array_agg_custom_cut(anyarray)
    RETURNS anyarray
        AS 'SELECT $1[2:array_length($1, 1)]'
    LANGUAGE SQL IMMUTABLE;
    
    DROP AGGREGATE IF EXISTS array_agg_custom(anyarray);
    CREATE AGGREGATE array_agg_custom(anyarray)
    (
        SFUNC = array_cat,
        STYPE = anyarray,
        FINALFUNC = array_agg_custom_cut,
        INITCOND = $${{'', '', ''}}$$
    );
    

    查询:

    SELECT
        array_agg_custom(
            ARRAY[
                alert_type::text,
                id::text,
                CAST(extract(epoch FROM date_happened) AS text)
            ])
    FROM e;
    

    结果:

                  array_agg_custom              
    --------------------------------------------
     {{red,1,1305036906},{yellow,2,1308787279}}
    (1 row)
    

    编辑:

    这是第二种更短的方法(也就是说,您不需要array_agg_custom_cut 函数,但正如您所见,查询中需要额外的ARRAY 级别):

    CREATE AGGREGATE array_agg_custom(anyarray)
    (
        SFUNC = array_cat,
        STYPE = anyarray
    );
    
    SELECT
        array_agg_custom(
            ARRAY[
                ARRAY[
                    alert_type::text,
                    id::text,
                    CAST(extract(epoch FROM date_happened) AS text)
                ]
            ])
    FROM e;
    

    结果:

                  array_agg_custom              
    --------------------------------------------
     {{red,1,1305036906},{yellow,2,1308787279}}
    (1 row)
    

    【讨论】:

    • 感谢您的提示。我使用了第二种方法,除了我创建了一个新的多态函数——array_append(anyarray,anyarray)——它只执行“SELECT array_cat($1, ARRAY[$2])”,然后使用 array_append 作为我的自定义聚合函数的 SFUNC。这样就不需要外部 ARRAY[] 包装器,从而使用户可见的 SQL 看起来更简单。 :)
    【解决方案2】:

    或将数组转换为像 array_agg(array[xxx, yyy]::text) 这样的文本

    array_agg(ARRAY[e.alert_type::text, e.id::text,
    cast(extract(epoch from e.date_happened) as text)]::text
    order by e.date_happened asc, e.id asc)
    

    【讨论】:

    • 只要你之后使用 regexp_replace() 来消除不需要的 " 字符,就可以发挥魅力。不需要自定义函数,所以我想更便携。
    猜你喜欢
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多