MySQL 8.0中JSON_ARRAYAGG函数如何优雅聚合关联表数据?

千萱大大_2402

千萱大大_2402

2026-09-23

472人浏览

原创

json_arrayagg不能跨表直接聚合,必须先join或派生表拉平数据再group by聚合;因其只接受当前行集表达式,不支持标量子查询,否则报错或退化为n+1查询。

mysql 8.0中json_arrayagg函数如何优雅聚合关联表数据?

直接结论:JSON_ARRAYAGG 本身不能跨表聚合,必须先通过 JOIN 或 LATERAL(MySQL 不支持)/派生表把关联数据“拉平”到同一行集里,再聚合;否则会报错或语义错误。

为什么不能在 JSON_ARRAYAGG 里直接写子查询?

常见错误是试图这样写:

SELECT id, JSON_ARRAYAGG((SELECT name FROM tags WHERE post_id = posts.id)) FROM posts;

这会触发 MySQL 报错:This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA。因为 JSON_ARRAYAGG 是聚合函数,只接受当前查询输出列(即 FROM + JOIN 后的临时结果集)中的表达式,不接受标量子查询。

  • 子查询在聚合上下文里无法被正确标记为“可重复执行”,MySQL 拒绝执行
  • 即使语法侥幸通过(如某些旧版兼容模式),性能也极差:对每行都执行一次子查询,变成类 N+1 查询
  • 正确路径永远是:先 JOIN → 再 GROUP BY → 最后 JSON_ARRAYAGG

JOIN + GROUP BY 是最稳的组合方式

假设你有 postscomments 两张表,想为每个 post 生成一个 comments 数组:

Comprehensive Three.js 3D graphics reference
Comprehensive Three.js 3D graphics reference

详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。

下载
SELECT 
  p.id,
  p.title,
  JSON_ARRAYAGG(
    JSON_OBJECT('id', c.id, 'content', c.content, 'created_at', c.created_at)
  ) AS comments
FROM posts p
LEFT JOIN comments c ON p.id = c.post_id
GROUP BY p.id, p.title;
  • LEFT JOIN 确保没有评论的 post 也能出现,此时 JSON_ARRAYAGG 返回空数组 [](不是 NULL
  • GROUP BY 必须包含所有非聚合列(p.id, p.title),否则 MySQL 8.0+ 会报 Expression #X of SELECT list is not in GROUP BY clause
  • 如果用 INNER JOIN,则只有带评论的 post 才会出现在结果里

遇到 NULL 值和大数据量时怎么避坑?

JSON_ARRAYAGGNULL 字段默认保留为 null 元素,比如 [{"id":1,"content":"ok"},{"id":2,"content":null}],前端解析容易出错;同时大数据量下可能被截断。

  • 过滤 NULL 字段:加 WHERE c.content IS NOT NULL,或用 IFNULL(c.content, '') 替换
  • 避免数组截断:检查并调高 group_concat_max_lenJSON_ARRAYAGG 复用其缓冲区),例如:SET SESSION group_concat_max_len = 1048576;
  • 若单条 JSON 数组超大(如 > 4MB),还需确认 max_allowed_packet 足够,否则连接直接中断

嵌套结构别手拼 JSON 字符串

有人会这么干:

CONCAT('{ "post": ', JSON_OBJECT('id', p.id, 'title', p.title), 
        ', "comments": ', JSON_ARRAYAGG(...), '}')

这是危险操作——JSON_ARRAYAGG 输出的字符串里的双引号不会被自动转义,最终得到非法 JSON。

  • 正确做法是全程用 JSON 函数嵌套:JSON_OBJECT('post', JSON_OBJECT(...), 'comments', JSON_ARRAYAGG(...))
  • MySQL 会自动处理引号、转义、类型转换,保证输出是合法 JSON
  • 一旦看到 CONCATJSON_ARRAYAGG 混用,基本可以判定该字段不可靠

真正麻烦的不是语法,而是忘记 GROUP BY 的粒度是否匹配业务分组意图,以及没意识到 JSON_ARRAYAGG 的内存行为会受 group_concat_max_len 静默限制——这两个点最容易在线上突然暴露。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql js json mysql 8.0

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

1933

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1179

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

695

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

2512

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

4108

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

979

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

4391

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

3982

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

5114

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 169人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 274人学习