我的数据库中有一个名为min_crew
的列,它有不同的字符数组,例如'{CA, FO, FA}'
。
我有一个查询,我试图获取这些数组的聚合但没有成功:
SELECT use.user_sched_id, array_agg(se.sched_entry_id) AS seids
, array_agg(se.min_crew)
FROM base.sched_entry se
LEFT JOIN base.user_sched_entry use ON se.sched_entry_id = use.sched_entry_id
WHERE se.sched_entry_id = ANY(ARRAY[623, 625])
GROUP BY user_sched_id;
623和625都具有相同的use.user_sched_id
,因此结果应该是seid和min_crew
的分组,但我只是不断收到此错误:
ERROR: could not find array type for data type character varying[]
如果我删除了代码的array_agg(se.min_crew)
部分,我会收到一张包含user_sched_id = 2131
和seids = '{623, 625}'
的表格。
答案 0 :(得分:9)
标准聚合函数array_agg()
仅适用于基类型,而不适用于作为输入的数组类型。
(但 Postgres 9.5 + 有一个new variant of array_agg()
可以!)
您可以使用此相关答案中定义的自定义汇总功能 array_agg_mult()
:
Selecting data into a Postgres array
每个数据库创建一次。然后您的查询可以这样工作:
SELECT use.user_sched_id, array_agg(se.sched_entry_id) AS seids
,array_agg_mult(ARRAY[se.min_crew]) AS min_crew_arr
FROM base.sched_entry se
LEFT JOIN base.user_sched_entry use USING (sched_entry_id)
WHERE se.sched_entry_id = ANY(ARRAY[623, 625])
GROUP BY user_sched_id;
链接答案中有详细的理由。
在回复您的评论时,请考虑the manual on array types:
中的这句话多维数组必须具有每个维度的匹配范围。 不匹配会导致错误。
没有办法解决这个问题,数组类型不允许在Postgres中出现这种不匹配。 可以使用NULL值填充数组,以便所有维度都具有匹配的范围。
但是为了这个查询的目的,我宁愿将数组转换为逗号分隔的列表array_to_string()
,并使用string_agg()
聚合text
- 最好使用不同的分隔符。在我的示例中使用换行符:
SELECT use.user_sched_id, array_agg(se.sched_entry_id) AS seids
,string_agg(array_to_string(se.min_crew, ','), E'\n') AS min_crews
FROM ...
您可能希望首先考虑normalizing架构。通常,您将使用此示例中概述的单独表实现此类n:m关系:
How to implement a many-to-many relationship in PostgreSQL?