讲师中心 微信公众号
AI工具推荐 视频效率加速

怎么在MySQL中利用子查询实现复杂的JSON数据提取_通过JSON_TABLE嵌套

陌明大大_2424

陌明大大_2424

发布时间:2026-05-05 07:02:00

|

942人浏览过

|

来源于php中文网

原创

JSON_TABLE必须位于顶层FROM或JOIN中,不可嵌套于子查询FROM内;处理多层嵌套需两层JSON_TABLE配合JOIN,且过滤条件应置于ON子句以避免丢失主记录。

怎么在mysql中利用子查询实现复杂的json数据提取_通过json_table嵌套

JSON_TABLE 不能直接嵌套在子查询 FROM 子句里?

MySQL 不允许把 JSON_TABLE 当作普通表名写在子查询的 FROM 里,比如 SELECT * FROM (SELECT ... FROM JSON_TABLE(...)) t 这种写法会报错 ERROR 1248: Every derived table must have its own alias —— 不是因为语法错,而是 MySQL 解析器对 JSON_TABLE 的上下文支持有限,它必须出现在顶层 FROM 或显式 JOIN 中。

真正能用的方式是:把 JSON_TABLE 放在主查询的 FROM 或 JOIN 位置,再用外层查询包裹逻辑。如果非要“嵌套提取”,得靠两层 JSON_TABLE 配合 JOIN 实现,而不是子查询套子查询。

  • JSON_TABLE 必须紧跟在表名或别名之后,不能作为子查询返回的“虚拟表”被再次引用
  • 想对 JSON_TABLE 的结果再加工(比如过滤、聚合),只能在外层 SELECT 中做,不能把它塞进另一个 FROM ( ... )
  • 若原始 JSON 是多层嵌套对象 + 数组(例如 {"user": {"id": 1, "orders": [{"amt": 100}, {"amt": 200}]}}),需先用一层 JSON_TABLE 提取 user,再 JOIN 第二层 JSON_TABLE 处理 orders 数组

如何用 JOIN 连接两层 JSON_TABLE 提取嵌套数组?

典型场景:一个订单主记录含用户信息和订单明细数组,你想展开成“每个明细一行”,同时带上用户字段。不能只靠一层 JSON_TABLE,因为路径 '$.user.orders[*]' 只能拿到数组元素,拿不到 $.user.id 这类同级字段。

正确做法是:第一层 JSON_TABLE 提取根对象(如 '$'),把 user 对象作为一列;第二层用 JSON_TABLE 基于该列再次解析其内部数组。

SELECT 
  u.id AS user_id,
  u.name AS user_name,
  o.amt AS order_amt
FROM orders o_main
JOIN JSON_TABLE(
  o_main.data, 
  '$' COLUMNS (
    id INT PATH '$.user.id',
    name VARCHAR(50) PATH '$.user.name',
    orders JSON PATH '$.user.orders'
  )
) AS u ON TRUE
JOIN JSON_TABLE(
  u.orders, 
  '$[*]' COLUMNS (
    amt DECIMAL(10,2) PATH '$.amt'
  )
) AS o ON TRUE;
  • 第一层 JSON_TABLE 路径用 '$',把整个 JSON 当作根,从中抽 user.id、user.name 和 user.orders(保留为 JSON 类型)
  • 第二层 JSON_TABLE 输入是上一层的 u.orders 列,路径用 '$[*]' 遍历数组,每项生成一行
  • ON TRUE 是必需的连接条件,因为 JSON_TABLE 不基于键匹配,只是“横向展开”

WHERE 条件里怎么安全地用 JSON_TABLE 展开后的字段?

很多人试图在 WHERE 里直接写 o.amt > 100,但要注意:如果原始 JSON 中 orders 是空数组或 NULL,JSON_TABLE(u.orders, '$[*] ...') 会返回零行,导致整条记录从结果中消失 —— 这不是 bug,是 JOIN 的语义决定的。

kashen-mysql DDLtoExcel
kashen-mysql DDLtoExcel

解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。

下载

若你希望主记录保留(即使没订单明细),得改用 LEFT JOIN,并把过滤条件移到 ON 子句里,而不是 WHERE:

LEFT JOIN JSON_TABLE(
  u.orders, 
  '$[*]' COLUMNS (
    amt DECIMAL(10,2) PATH '$.amt'
  )
) AS o ON o.amt > 100
  • 用 LEFT JOIN 保证主记录不丢
  • 把 o.amt > 100 放在 ON 里,否则 WHERE o.amt > 100 会把 o 为 NULL 的行全滤掉
  • JSON_TABLE 对无效 JSON 返回空集,不会报错,但会导致关联丢失 —— 建议前置加 JSON_VALID(o_main.data) 过滤

性能关键点:别让 JSON_TABLE 成为全表扫描黑洞

JSON_TABLE 本身不走索引,每次执行都会解析整列 JSON 字符串。如果表有百万行,又没前置过滤,哪怕只取 10 行,也可能先解析全部 JSON 再 LIMIT —— 因为 MySQL 优化器无法下推 LIMIT 到 JSON_TABLE 展开前。

真正有效的优化只有两个方向:

  • 在 JOIN JSON_TABLE 前,用普通字段(如 status = 'active')或生成列索引(如 v_user_id)大幅缩小输入行数
  • 避免在大表上直接 SELECT ... FROM big_table, JSON_TABLE(...),先用子查询或 CTE 把目标主键拎出来,再关联展开
  • 如果只是偶尔查,且 JSON 结构固定,长期方案仍是建生成列 + 索引,而不是依赖 JSON_TABLE 实时解析

最易被忽略的是:JSON 字段长度越大、嵌套越深、数组元素越多,JSON_TABLE 单行解析耗时就呈非线性增长 —— 测试时用几条数据没问题,上线后数据量翻十倍,响应可能从 50ms 涨到 2s。

热门AI工具

更多
二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

相关专题

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

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

2413

2023.06.20

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

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

1459

2023.06.21

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

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

855

2023.07.18

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

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

3412

2023.07.19

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

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

5848

2023.07.25

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

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

1259

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

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

6111

2023.08.11

mysql忘记密码
mysql忘记密码

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

5282

2023.08.14

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

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

精品课程

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

共1课时 | 193人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn