json_table的核心价值是将json解析下推至数据库内核,需严格遵循路径规则、分层嵌套语法及on empty/on error显式处理,且其隐式lateral连接会导致行数膨胀。

直接在 SQL 里把 JSON 打平成行,不用拉到应用层解析 —— 这是 JSON_TABLE 的核心价值。它不是语法糖,而是把 JSON 解析逻辑下推到数据库内核的强制能力。
路径表达式写错就报 ERROR 3143 或 3149
路径必须合法且匹配实际数据结构,否则查询直接失败。
-
'$[*]'仅适用于根级数组;若源字段是对象(如{"items": []}),却写'$[*]',会报ERROR 3149 (HY000): The JSON path is not valid for the given JSON document - 漏引号、用双斜杠
//、写成'$.[*]'(中间多点)等,触发ERROR 3143 (42000): Invalid path expression - 路径指向字段存在但类型不匹配:比如
PATH '$.price'期望数字,但 JSON 里存的是字符串"price": "99.99",也会返回NULL或报错,取决于是否加了ON ERROR
嵌套数组必须用 NESTED PATH,不能硬套多层 COLUMNS
当 JSON 是“对象包数组”结构(如 {"order_id": 1, "items": [{"id": 101}, {"id": 102}]}),想同时取顶层字段和数组元素,必须分层定义。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 错误写法:
JSON_TABLE(o.data, '$' COLUMNS (order_id INT PATH '$.order_id', item_id INT PATH '$.items[*].id'))——$.items[*].id在非根级路径中不被允许,结果为空或报错 - 正确写法:外层取对象字段,
NESTED PATH '$.items[*]'单独展开数组,其子COLUMNS中的PATH自动以当前数组元素为基准(即$指代{"id": 101}) -
NESTED PATH必须嵌套在最外层COLUMNS内,不可独立存在;每加一层,输出行数按该数组长度膨胀
列定义里 PATH 是相对路径,不是从根开始拼的
每个 COLUMNS 子句里的 PATH,都相对于它所属的路径上下文(主 path 或某层 NESTED PATH)。
- 主路径是
'$.items[*]',那么COLUMNS (name VARCHAR(50) PATH '$.name')中的$就指代每个items数组元素,不是整个原始 JSON - 主路径是
'$',又用了NESTED PATH '$.items[*]',那它内部的PATH '$.id'的$就是当前items元素,不是原始 JSON 的根 - 误写成
PATH '$.items[0].id'这类越界路径,即使数据有值,也可能返回NULL—— 因为它试图从当前上下文再往下找items字段,而当前上下文已经是items的某个元素了
空值和异常要显式控制,别依赖默认行为
生产 JSON 数据质量差,字段缺失、类型错乱极常见。ON EMPTY 和 ON ERROR 不是可选项,是必填项。
- 不写
ON EMPTY,字段缺失时行为未定义,可能返回NULL,也可能报错,取决于 MySQL 版本和配置 - 不写
ON ERROR,类型转换失败(如字符串转INT)可能中断整个查询,而不是跳过该行 - 推荐写法:所有列都明确补上
ON EMPTY NULL ON ERROR NULL,尤其在聚合或 JOIN 场景下,避免意外中断
最容易被忽略的一点:JSON_TABLE 返回的是虚拟表,它参与的是隐式 LATERAL 连接 —— 每一行输入 JSON 都会独立执行一次解析。这意味着,如果源表有 10 万行,而每行 JSON 展开成 5 行,最终结果就是 50 万行,且无法用普通索引加速解析过程。提前评估膨胀比,比写对路径更重要。










