如何在MySQL中对JSON数组进行展开查询_使用JSON_TABLE函数

夏杰小哥_3401

夏杰小哥_3401

2026-05-07

892人浏览

原创

json_table 是 mysql 8.0.4+ 用于将 json 数组展开为关系型行集的原生函数,必须在 from 子句中使用,适用于权限、商品 id 等数组字段展开场景。

如何在mysql中对json数组进行展开查询_使用json_table函数

JSON_TABLE 是什么,什么时候必须用它

JSON_TABLE 是 MySQL 8.0.4+ 引入的函数,用于把 JSON 数组“炸开”成关系型行集。它不是语法糖,而是唯一能原生将嵌套 JSON 数组转为多行结果的方式——JSON_EXTRACT 或 -> 操作符只能取值,不能展开;想用 JOIN 或子查询硬凑,会漏数据或爆炸式笛卡尔积。

常见场景包括:

  • 表中某字段存了用户权限列表:{"roles": ["admin", "editor"]},要查所有带 admin 的用户
  • 订单记录里存了商品 ID 数组:{"items": [101, 102, 105]},需关联商品表查明细
  • 日志字段含操作步骤数组,要统计每步耗时分布

基本写法:FROM 子句里直接调用 JSON_TABLE

JSON_TABLE 必须出现在 FROM 子句中(不能放 SELECT 里),结构固定为:

JSON_TABLE(
  json_doc,
  path COLUMNS (column_def, ...)
) AS alias

关键点:

Feishu calendar sync, local ics to json data for AI agent
Feishu calendar sync, local ics to json data for AI agent

将ICS日历文件转为JSON格式,用于飞书日历导入导出及数据集成。

下载
  • json_doc 是源 JSON,可以是列名(如 data)、表达式(如 data->'$.items')或字面量(如 '[1,2,3]')
  • path 是数组路径,必须以 $[<em>]</em> 结尾,例如 '$.roles[]'、'$[*]'
  • COLUMNS 定义输出列:支持 name FOR ORDINALITY(序号)、name VARCHAR(20) PATH '$'(取当前数组元素值)、name INT PATH '$.id'(取对象子字段)

示例:从 users 表展开 roles 数组

SELECT u.id, jt.role
FROM users u,
JSON_TABLE(u.profile, '$.roles[*]' COLUMNS (role VARCHAR(20) PATH '$')) AS jt;

常见错误和坑点
  • 报错 ERROR 3143 (42000): Invalid path expression:路径没写 [<em>]</em>,比如用了 '$.roles' 而非 '$.roles[]'
  • 展开后行数为 0:源 JSON 字段为 NULL、空字符串、或根本不是合法 JSON(可用 JSON_VALID(data) 先过滤)
  • 字段类型不匹配导致截断:比如用 VARCHAR(5) 接长度为 8 的字符串,静默截断不报错
  • 对象数组里取深层字段写错路径:若数组元素是 {"user": {"name": "Alice"}},正确写法是 name VARCHAR(50) PATH '$.user.name',不是 '$.name'
  • 性能隐患:对大表 + 大 JSON 字段频繁展开,建议在应用层预处理,或加生成列 + 索引(如 ALTER TABLE users ADD role_list TEXT AS (profile->>'$.roles'))

和 JSON_CONTAINS 配合做条件过滤

单纯展开不够,常需边展开边过滤。别在 WHERE 里对原始 JSON 字段用 JSON_CONTAINS(无法利用展开逻辑),而应先展开再筛:

SELECT u.id, jt.role
FROM users u,
JSON_TABLE(u.profile, '$.roles[*]' COLUMNS (role VARCHAR(20) PATH '$')) AS jt
WHERE jt.role = 'admin';

如果要查“同时有 admin 和 editor”的用户,得用聚合(如 HAVING COUNT(DISTINCT jt.role) = 2)或两次 EXISTS 子查询——JSON_TABLE 本身不支持跨行逻辑判断。

JSON_TABLE 的路径解析和列映射是静态的,运行时不推导结构。一旦 JSON 格式变化(比如数组变对象、字段名改大小写),查询会静默返回空或错列,上线前务必用真实数据验证。

相关专题

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

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

2023.06.20

2093

6

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

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

2023.06.21

1279

5

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

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

2023.07.18

755

5

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

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

2023.07.19

2812

5

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

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

2023.07.25

4668

4

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

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

2023.08.08

1079

3

sqlserver和mysql区别
sqlserver和mysql区别

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

2023.08.11

4931

4

mysql忘记密码
mysql忘记密码

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

2023.08.14

4402

7

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

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

2023.08.16

5754

11

热门下载

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

精品课程

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

共1课时 | 178人学习

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

共2课时 | 285人学习