MySQL 5.7+ 支持 JSON_EXTRACT() 但仅返回单个 JSON 值,无法展开数组;真正摊开嵌套数组需用 MySQL 8.0.4+ 的 JSON_TABLE 配合 LATERAL JOIN,并注意 JSON_VALID 校验、字符集和生成列索引优化。
JSON_EXTRACT在MySQL中根本不存在
MySQL 5.7+ 原生支持的是
函数,但注意:它不是你想象中那个能直接展开数组、返回多行的“万能解析器”。它的行为非常明确——只返回一个 JSON 类型的值(比如字符串、数字、对象或数组),且结果仍包裹在双引号或方括号里。常见错误是写成
后直接拿去
或
,结果报错或逻辑错乱,因为返回的是
这样的 JSON 字符串,不是可枚举的行集。
真正能“摊开”嵌套数组的是JSON_TABLE
MySQL 8.0.4+ 引入了
,这才是处理多层嵌套、尤其是带数组结构的正解。它把一段 JSON 当作虚拟表来 JOIN,天然支持路径映射、类型转换和层级展开。
必须用
关键字配合
,否则无法引用上游表的 JSON 字段
路径表达式里不能用
通配符直接写在最外层;要写成
这种显式列定义
嵌套数组需用嵌套的
,例如先展开
,再对每个
的
字段再套一层
示例:从
中提取所有商品标题
别忽略JSON_VALID和字符集问题
生产环境中,JSON 字段常混入非法字符(如未转义的换行、控制符)或编码不一致(UTF-8 vs GBK),导致
直接报错退出,整条 SQL 失败。必须前置校验:
Find JSON Path Online
Easily find JSON paths within JSON objects using our intuitive Json Path Finder
下载
用
过滤掉脏数据,避免中断执行
确保字段声明为
类型,而非
或
;后者即使内容合法,
也可能因隐式转换失败
导入时若用
,记得加
性能陷阱:别在WHERE里反复调用JSON函数
像
这种写法,每行都会触发一次 JSON 解析,且无法走索引。更糟的是,如果同时写多个
,解析次数翻倍。
正确做法:提前用生成列(generated column)+ 索引固化常用路径,例如
,再给
加索引
临时分析场景可用
预解析一次,避免重复调用
和
在匹配数组时比多次
更高效
复杂嵌套真正难的不是语法,而是路径是否完整覆盖所有分支、空数组/空对象是否被显式处理、以及生成列索引是否真正生效——这些地方一漏,查出来就是静默丢数。
JSON_EXTRACT()JSON_EXTRACT(json_col, '$.items[*].name')WHEREGROUP BY["a","b"]JSON_TABLELATERALJOIN[*]COLUMNS (name TEXT PATH '$.name')JSON_TABLE$.shopsshopproductsJSON_TABLEpage_dataSELECT jt1.shop_id, jt2.title
FROM t,
JSON_TABLE(page_data, '$.shops[*]' COLUMNS (
shop_id STRING PATH '$.shop_id',
products JSON PATH '$.products'
)) AS jt1,
JSON_TABLE(jt1.products, '$[*]' COLUMNS (
title STRING PATH '$.title'
)) AS jt2;JSON_TABLEJSON_VALID(json_col)JSONTEXTVARCHARJSON_TABLELOAD DATA INFILECHARACTER SET utf8mb4WHERE JSON_EXTRACT(data, '$.user.id') = '123'JSON_EXTRACTALTER TABLE t ADD user_id BIGINT AS (JSON_EXTRACT(data, '$.user.id')) STOREDuser_idCTEJSON_CONTAINSJSON_OVERLAPSJSON_EXTRACT