JSON_TABLE解析嵌套数组必须分步或使用NESTED PATH:先用主路径(如'$.data[*]')展开外层数组,再通过NESTED PATH '$.tags[*]'展开子数组并定义列,不可跨层级通配;低于8.0.22需两层JSON_TABLE配合LATERAL关联。

JSON_TABLE 解析嵌套数组时必须显式指定路径层级
MySQL 的 JSON_TABLE 不会自动展开多层嵌套,比如 {"data": [{"id": 1, "tags": ["a","b"]}]} 中的 tags 数组,不能直接用 $[*].tags 提取——它只识别最外层的数组路径。必须先用一次 JSON_TABLE 拆出对象行,再对每行的字段做二次解析。
常见错误现象:Column 'tags' cannot be null 或返回空结果,往往是因为路径写成 $[*].tags[*] 这类跨层级通配,MySQL 8.0.22+ 才支持部分嵌套路径语法,但稳定写法仍是分步。
- 第一层:用
JSON_TABLE(... COLUMNS (id FOR ORDINALITY, item JSON PATH '$'))把数组元素转为行,并保留原始 JSON 字符串 - 第二层:对
item列再套一层JSON_TABLE(item COLUMNS (...))解析其内部字段或子数组 - 注意:外层
PATH必须指向数组(如'$.data[*]'),不能是对象(如'$.data')否则只返回一行
解析子数组(如 tags)要用 NESTED PATH + COLUMNS
想把每个对象里的 tags 数组展开成多行(一对多),不能靠两次独立的 JSON_TABLE,得用 NESTED PATH 子句。这是唯一能在一个 JSON_TABLE 调用中完成“主对象→子数组→子项”三级展开的方式。
使用场景:日志记录含用户行为标签、订单含多个商品 SKU、配置含多组开关项。
-
NESTED PATH '$.tags[*]' COLUMNS (tag VARCHAR(20) PATH '$')是标准写法;PATH '$.tags[*]'必须带[*],否则不识别为数组 - 若子数组项是对象(如
[{"name":"x","val":1}]),可在COLUMNS里继续用name VARCHAR(20) PATH '$.name' - 性能影响:嵌套越深、数组越大,解析开销越高;避免在 WHERE 中对
JSON_TABLE输出列做函数运算,会导致无法走索引
MySQL 版本和字符集导致 JSON 解析失败
JSON_TABLE 在 MySQL 8.0.4 引入,但完整支持 NESTED PATH 要求 8.0.22+。低于该版本执行会报错:FUNCTION does not exist: JSON_TABLE 或 Syntax error near 'NESTED'。
另一个隐蔽坑是字符集:源 JSON 若含 UTF-8 多字节字符(如中文、emoji),而字段定义为 VARCHAR(50) 但连接字符集是 latin1,会导致截断或乱码,表现为部分字段为空或乱码值。
- 检查版本:
SELECT VERSION();,低于 8.0.22 就别硬上NESTED PATH - 确保连接字符集为
utf8mb4:SET NAMES utf8mb4;,且目标表字段也用utf8mb4_unicode_ci - 调试技巧:先用
SELECT JSON_EXTRACT(@json, '$.data[0].tags')确认路径是否有效,再移植到JSON_TABLE
NULL 值和缺失字段的处理逻辑容易被忽略
JSON_TABLE 默认对不存在的字段返回 NULL,但若声明了 NOT NULL 约束(如 id INT NOT NULL PATH '$.id'),遇到缺失字段会整行丢弃——不是填 NULL,而是跳过该 JSON 元素。
这在数据质量不统一时极难排查,比如一批 JSON 有的带 status,有的不带,用 status ENUM('ok','fail') NOT NULL PATH '$.status' 就会漏掉所有没 status 的记录。
- 安全写法:所有字段都用
PATH后加DEFAULT NULL ON EMPTY(MySQL 8.0.29+)或干脆去掉NOT NULL - 兼容旧版:用
COALESCE(status, 'unknown')在外层 SELECT 中兜底 - 特别注意:空字符串
""和NULL在 JSON 中语义不同,ON EMPTY不捕获空字符串,需额外用CASE WHEN status = '' THEN 'empty' ELSE status END
实际嵌套解析往往要组合路径提取、嵌套展开、空值兜底三层逻辑,少一个环节就可能查不到数据——尤其是生产环境 JSON schema 有波动时,最容易卡在“看起来语法对,但结果为空”。











