2

如何在 pl/pgsql 中合并/组合数组?

例如,我有 3 个数组:{1,2,3}{"a","b","c"}{32,43,23}

合并后我需要得到:

{{1,"a",32}, {2,"b",43}, {3,"c",23}}

我的 PostgreSQL 版本是 9.0

4

1 回答 1

4

听起来您想要一个 n 参数zip函数,就像在某些函数式语言和具有函数式扩展的语言中所发现的那样。

在这种情况下,您不能完全按照您的意愿进行操作,因为这些数组属于异构类型。PostgreSQL 数组必须是同质类型的,所以这不起作用。您显示的所需结果是无效数组。

您可以创建一个 s 数组ROW(匿名记录),或将所有值转换为text.

例如:

SELECT array_agg(ROW(a,b,c)) 
FROM (
  SELECT 
    unnest('{1,2,3}'::integer[]),
    unnest('{"a","b","c"}'::text[]),
    unnest('{32,43,23}'::integer[])
)
x(a,b,c);

将产生:

{"(1,a,32)","(2,b,43)","(3,c,23)"}

这是一个转换为文本的三个行类型的数组。使用起来会很尴尬,因为 Pg 对匿名记录的支持非常有限;最重要的是,在这种情况下,您不能将文本值强制转换为,而RECORD(integer,text,integer)实际上必须CREATE TYPE强制转换为定义的类型。

由于该限制,您可能希望将所有值转换为text并使用text. 您希望能够使用简单的 来做到这一点array_agg,但令人沮丧的是,这失败了:

SELECT array_agg(ARRAY[a::text,b,c::text]) 
FROM (
  SELECT 
    unnest('{1,2,3}'::integer[]),
    unnest('{"a","b","c"}'::text[]),
    unnest('{32,43,23}'::integer[])
)
x(a,b,c);

生产:

ERROR:  could not find array type for data type text[]

因为array_agg不支持数组作为输入。您需要定义另一个array_agg接受text[]输入的变体。前段时间写过一篇,现在找不到了;如果我找到它,我会尝试找到它并更新。同时,您可以通过将内部数组转换为text

SELECT array_agg(ARRAY[a::text,b,c::text]::text) 
    FROM (
      SELECT 
        unnest('{1,2,3}'::integer[]),
        unnest('{"a","b","c"}'::text[]),
        unnest('{32,43,23}'::integer[])
    )
    x(a,b,c);

产生如下输出:

 {"{1,a,32}","{2,b,43}","{3,c,23}"}

...好吧,我还没有找到我写的那个,但这里有一个来自 Erwin 的例子,它做得很好。试试这个:

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

SELECT array_agg_mult(ARRAY[ARRAY[a::text,b,c::text]]) 
FROM (
  SELECT 
    unnest('{1,2,3}'::integer[]),
    unnest('{"a","b","c"}'::text[]),
    unnest('{32,43,23}'::integer[])
)
x(a,b,c);

输出:

 {{1,a,32},{2,b,43},{3,c,23}}
于 2013-01-04T02:10:01.470 回答