如何在pl / pgsql中合并/组合数组?
例如我有3个数组:{1,2,3}
,{"a","b","c"}
和{32,43,23}
合并后我需要得到:
{{1,"a",32}, {2,"b",43}, {3,"c",23}}
我的PostgreSQL版本是9.0
答案 0 :(得分:4)
听起来你想要一个n参数zip
函数,就像某些函数式语言和带有函数扩展的语言一样。
在这种情况下,你无法完全按照你想要的那样做,因为那些数组是非典型的。 PostgreSQL数组必须是同类型的,所以这不会起作用。您显示的所需结果是无效数组。
您可以创建一个ROW
s(匿名记录)数组,或将所有值转换为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}"}
......好吧,我还没找到我写的那个,但是here's an example from Erwin that does the job fine。试试这个:
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}}