ARRAY_AGG默认返回原生数组类型(如text[]),非JSON;要生成JSON数组需显式转换,如to_jsonb(ARRAY_AGG(to_jsonb(t)))或直接用JSONB_AGG,后者更简洁高效且自动处理NULL。

ARRAY_AGG 生成 JSON 数组时为什么结果是字符串而不是 JSON 类型
PostgreSQL 的 ARRAY_AGG 默认返回 text[] 或基础类型数组,不是 JSON;直接转 json 或 jsonb 需显式转换。常见错误是写成 ARRAY_AGG(row_to_json(t))::json 却发现外层多了一对方括号但类型仍是 text,本质是字符串拼接而非合法 JSON 值。
正确做法是先用 row_to_json 或 to_jsonb 把每行转为 JSON 值,再用 ARRAY_AGG 聚合成数组,最后用 to_jsonb(或 array_to_json)整体转成 JSON 数组:
SELECT to_jsonb(ARRAY_AGG(to_jsonb(t))) FROM (VALUES (1,'a'),(2,'b')) AS t(id, name);
-
to_jsonb(t)确保单行输出为jsonb类型,不是字符串 -
ARRAY_AGG(...)得到jsonb[]类型数组(非字符串数组) -
to_jsonb(...)将整个数组转为标准 JSON 数组值(类型jsonb),可被上层应用直接解析 - 若用
array_to_json(ARRAY_AGG(...))也可,但它不处理 NULL 元素,默认跳过;to_jsonb会保留 NULL
用 JSONB_AGG 替代 ARRAY_AGG + to_jsonb 更简洁
PostgreSQL 9.5+ 提供了原生聚合函数 JSONB_AGG,一步到位生成 jsonb 数组,语义清晰、性能略优,且自动处理 NULL(默认包含)。
SELECT JSONB_AGG(to_jsonb(t)) FROM (VALUES (1,'a'),(2,'b')) AS t(id, name);
-
JSONB_AGG输入必须是jsonb值,所以仍需to_jsonb(t)包裹每一行 - 它比
to_jsonb(ARRAY_AGG(...))少一次类型转换,执行计划更直接 - 不支持排序控制(如
ORDER BY子句)——这是关键限制:若需固定顺序,得在外层子查询中先排序,再聚合 - 若要排除 NULL 行,加
FILTER (WHERE t.id IS NOT NULL)
嵌套对象字段名丢失?用 JSONB_BUILD_OBJECT 显式构造
直接 to_jsonb(t) 依赖源表/子查询的列名,但若来源是 VALUES、计算字段或别名未保留,JSON 键名可能出人意料(如 "column1"、"column2")。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
安全做法是用 JSONB_BUILD_OBJECT 显式指定键名:
SELECT JSONB_AGG(
JSONB_BUILD_OBJECT(
'id', t.id,
'name', t.name,
'is_active', t.id > 0
)
) FROM (VALUES (1,'a'),(2,'b')) AS t(id, name);
- 避免依赖隐式列名,结构可控
- 支持表达式字段(如布尔计算、函数调用),
to_jsonb(t)对复杂表达式不友好 - 若某字段可能为 NULL 且不想出现在 JSON 中,需额外用
CASE或JSONB_STRIP_NULLS处理
GROUP BY 场景下聚合 JSON 数组容易漏掉空组
当配合 GROUP BY 使用 JSONB_AGG,若某组无匹配行(例如 LEFT JOIN 右侧为空),该组结果为 NULL,而非空 JSON 数组 []。前端解析时常因此报错。
- 用
COALESCE(JSONB_AGG(...), '[]'::jsonb)补空数组 - 注意:不能写
COALESCE(JSONB_AGG(...), JSONB_BUILD_ARRAY()),因为JSONB_AGG在空组时返回NULL,而JSONB_BUILD_ARRAY()是空数组,类型一致可安全 coalesce - 若 GROUP BY 字段本身来自 LEFT JOIN,确保 ON 条件没意外过滤掉空组
最易忽略的是:空组补 [] 后,前端仍需判断数组长度,不能假设非空——业务逻辑里“无子项”和“子项为空数组”有时语义不同。

















