JSON_ARRAYAGG是MySQL 8.0+唯一原生行转JSON数组聚合函数,需配合GROUP BY使用,支持ORDER BY排序、NULL处理及JSON_OBJECT嵌套,输出为JSON类型值。

JSON_ARRAYAGG 是 MySQL 8.0+ 唯一原生支持的行转 JSON 数组聚合函数,低版本(如 5.7)直接调用会报 FUNCTION xxx.JSON_ARRAYAGG does not exist 错误。
必须搭配 GROUP BY 使用,否则整表压成一个数组
它不是标量函数,不能脱离分组上下文单独使用。哪怕你只想把全表所有行聚合成一个数组,也得显式写 GROUP BY ()(空分组)或加个恒真条件(如 GROUP BY 1)。
- 错误写法:
SELECT JSON_ARRAYAGG(name) FROM users;→ 返回单个数组,但语义模糊、不可控,且在严格 SQL 模式下可能报错 - 正确写法:
SELECT JSON_ARRAYAGG(name) AS all_names FROM users GROUP BY ();(MySQL 8.0.23+ 支持)或SELECT JSON_ARRAYAGG(name) AS all_names FROM users GROUP BY 1; - 实际业务中几乎总是配合真实分组字段,比如按
dept_id、category分组,否则失去聚合意义
ORDER BY 控制元素顺序,NULL 默认被跳过
JSON_ARRAYAGG() 支持内联 ORDER BY,这是和 GROUP_CONCAT() 的关键区别之一——它保持 JSON 类型,不拼字符串。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 升序排列员工 ID:
JSON_ARRAYAGG(id ORDER BY id ASC) - 按创建时间倒序排文章标题:
JSON_ARRAYAGG(title ORDER BY created_at DESC) - NULL 值默认不进入数组;若需保留
null元素,得提前用IFNULL(col, CAST(NULL AS JSON))或COALESCE(col, JSON_OBJECT())处理(注意:直接COALESCE(col, NULL)无效,仍会被跳过)
嵌套对象要用 JSON_OBJECT 配合,不能直接传多列
想让数组里每个元素是 {"id": 1, "name": "Alice"} 这样的对象?不能写 JSON_ARRAYAGG(id, name) ——语法错误,函数只接受单个表达式。
- 正确组合:
JSON_ARRAYAGG(JSON_OBJECT('id', id, 'name', name)) - 常见错误:
JSON_ARRAYAGG((SELECT JSON_OBJECT(...) FROM ...))→ 报错This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA,必须先 JOIN 或用 LATERAL(MySQL 8.0.14+)拉平数据 - 性能注意:嵌套越深、字段越多,内存占用越高;大数据量下容易触发
max_allowed_packet限制(即使结果没超限,中间构建过程也可能失败)
别和 GROUP_CONCAT 混用,也别信 CONCAT + JSON_ARRAYAGG
有人试图用 CONCAT('[', GROUP_CONCAT(...), ']') 模拟 JSON 数组,这极其危险:字段含引号、反斜杠、换行时必然破坏 JSON 格式,且类型全变成字符串。
-
JSON_ARRAYAGG()自动处理引号转义、类型推导(数字不加引号、TRUE/FALSE保持布尔字面量) - 它底层复用
group_concat缓冲机制,所以仍受group_concat_max_len影响;超长时会静默截断,建议同步调大该变量 - 如果聚合结果要给前端直接
JSON.parse(),务必用JSON_ARRAYAGG,别省那点理解成本去手拼
真正容易被忽略的是:它的输出是 JSON 类型值,不是字符串。如果后续还要用 JSON_CONTAINS、JSON_EXTRACT 等函数进一步处理,这点很关键;但如果只是 SELECT 出来当文本传给应用层,MySQL 客户端默认会做一次隐式转换,看起来像字符串——别被表象骗了。

















