如何在 pl/pgsql 中合并/组合数组?
例如,我有 3 个数组:{1,2,3}
、{"a","b","c"}
和{32,43,23}
合并后我需要得到:
{{1,"a",32}, {2,"b",43}, {3,"c",23}}
我的 PostgreSQL 版本是 9.0
如何在 pl/pgsql 中合并/组合数组?
例如,我有 3 个数组:{1,2,3}
、{"a","b","c"}
和{32,43,23}
合并后我需要得到:
{{1,"a",32}, {2,"b",43}, {3,"c",23}}
我的 PostgreSQL 版本是 9.0
听起来您想要一个 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}}