array_agg 默认保留 null 值,导致后续 unnest 或解析出错;空组返回 null 而非空数组,需用 coalesce 补空;order by 必须写在函数内部;字符串拼接应使用 array_to_string 或直接 string_agg;不支持嵌套 array_agg 生成多维数组。

ARRAY_AGG 会把 NULL 值也塞进数组里吗?
会,ARRAY_AGG 默认保留 NULL 值——这常导致后续 UNNEST 或应用层解析出错。比如:SELECT ARRAY_AGG(name) FROM users GROUP BY dept; 若某组含 NULL,结果可能是 {'Alice',NULL,'Bob'}。
- 用
ARRAY_AGG(col ORDER BY col) FILTER (WHERE col IS NOT NULL)显式过滤(推荐,语义清晰) - 或先在子查询中
WHERE col IS NOT NULL,再聚合(适合复杂条件) - 注意:空组(无匹配行)返回
NULL,不是空数组{};需用COALESCE(ARRAY_AGG(...), ARRAY[]::text[])补空
ORDER BY 在 ARRAY_AGG 里写在哪一层?
必须写在 ARRAY_AGG 函数内部,不能放在外部 GROUP BY 的 ORDER BY 子句里——后者只影响最终结果集顺序,不改变数组元素顺序。
- 正确:
ARRAY_AGG(name ORDER BY created_at DESC) - 错误:
ARRAY_AGG(name) ORDER BY created_at DESC(语法报错) - 多字段排序支持:
ARRAY_AGG(id ORDER BY status, updated_at DESC) - 若省略
ORDER BY,数组内元素顺序不确定(取决于扫描路径,不可依赖)
怎么把 ARRAY_AGG 结果转成字符串拼接?
别直接套 STRING_AGG——它和 ARRAY_AGG 是并列聚合函数,不是转换工具。真要字符串,要么换用 STRING_AGG,要么用 ARRAY_TO_STRING 转换数组。
- 简单拼接:
ARRAY_TO_STRING(ARRAY_AGG(name), ', ', '*')(第三参数是 NULL 替代符) - 带引号的 CSV:
ARRAY_TO_STRING(ARRAY_AGG(quote_literal(name)), ', ') - 性能注意:大数组 + 复杂分隔符时,
ARRAY_TO_STRING比原生STRING_AGG略慢,优先选后者 - 类型必须匹配:
ARRAY_AGG(int4)得转成text[]才能传给ARRAY_TO_STRING,否则报错
嵌套 ARRAY_AGG 导致多维数组,怎么扁平化?
PostgreSQL 不支持直接 ARRAY_AGG(ARRAY_AGG(...)) 生成二维数组(会报错“cannot aggregate arrays”)。常见于 “每个部门下按状态分组统计姓名” 这类需求。
- 用子查询 +
JSON_AGG更稳妥:SELECT dept, JSON_AGG(JSON_BUILD_OBJECT('status', status, 'names', names)) FROM (...) GROUP BY dept - 强行二维数组需用
ARRAY(SELECT ...)构造:ARRAY(SELECT ARRAY_AGG(name) FROM sub GROUP BY status),但可读性差、调试难 - 真正需要多维数组时,检查是否过度设计——多数业务场景用 JSON 或应用层处理更灵活
数组维度和 NULL 处理是 ARRAY_AGG 最容易翻车的两个点,写完务必用含 NULL 和空组的数据验证输出结构。











