问题How to use array_agg() for varchar[]的回答,
我们可以创建一个自定义聚合函数来聚合Postgres中的n维数组,如:
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
,STYPE = anyarray
,INITCOND = '{}'
);
约束是值必须共享相同的数组范围和相同的长度,处理空值和不同的长度不起作用。
答案:
没有办法,数组类型不允许这样的 Postgres不匹配。您可以使用NULL值填充数组 所有维度都有匹配的范围。
我有像
这样的行------ arrayfield
----- {1},
----- {},
----- {abc}
array_agg_mult(ARRAY[arrayfield]) AS customarray
我期待像{{1},NULL,{abc}}
但它会抛出
ERROR: cannot concatenate incompatible arrays
DETAIL: Arrays with differing element dimensions are not compatible for concatenation.
我们是否可以在自定义函数中添加填充值?
我发现问题是当数组 length 不同时。 {a},{null},{1}
将汇总,但{a,b},{},{1}
不会。
所以我需要一个查询,我可以在现有数组中添加NULL元素。
一种解决方案是始终追加两个NULL(2是该字段中的最大长度)array_cat(arr, ARRAY[NULL,NULL])
并将数组修剪为长度2:
{1} --> {1,NULL,NULL} --> {1,NULL}
{NULL} --> {NULL,NULL,NULL} --> {NULL,NULL}
{abc, def} --> {abc,def,NULL,NULL} --> {abc, def}
但我无法弄清楚语法。
答案 0 :(得分:1)
使用此相关答案中定义的自定义聚合函数array_agg_mult()
:
您的预期结果是不可能的:
{{1},NULL,{abc}}
必须是:
{{1},{NULL},{abc}}
对于简单的情况,只需替换空数组: 您可以通过以下方式实现这一目标:
WITH t(arr) AS (
VALUES
('{1}'::text[])
,('{}')
,('{abc}')
)
SELECT array_agg_mult(ARRAY[CASE WHEN arr = '{}' THEN '{NULL}' ELSE arr END])
FROM t;
使用array_fill()
填充NULL元素的数组,最大长度为:
SELECT array_agg_mult(ARRAY[
arr || array_fill(NULL::text
, ARRAY[max_elem - COALESCE(array_length(arr, 1), 0)])
]) AS result
FROM t, (SELECT max(array_length(arr, 1)) AS max_elem FROM t) t1;
仍然只适用于 1维基本数组。
t1
计算基本1维数组的最大长度。COALESCE(array_length(arr, 1), 0)
计算此行中数组的长度
对于COALESCE
,0
默认为NULL
。array_fill()
生成长度差异的填充数组。arr
||
array_agg_mult()
进行汇总。SQL Fiddle.演示全部 SQL小提琴中的输出具有误导性,因此我将结果转换为文本。