mysql json_extract 函数解析json字符串

本文介绍如何使用SQL语句中的json_extract函数从JSON字段中提取特定元素值的方法,并通过实际案例展示了如何针对不同字段进行有效解析。

参考自:

https://blog.youkuaiyun.com/weixin_43766560/article/details/107881312

https://blog.youkuaiyun.com/qq_34673519/article/details/104043722

https://blog.youkuaiyun.com/sinat_38804294/article/details/86357446

https://blog.youkuaiyun.com/yuhui123999/article/details/83539149

临时表方式:

https://blog.youkuaiyun.com/helloHuaKai/article/details/84852973

 

 

SELECT json_extract(字段名,'$.json结构') FROM 表名;

 

 

1. 获取json数据中的元素值

select json_extract(cost_detail, '$.costItems') '获取json指定字段值'  from xp_order where order_no ='OR202012030230477943158211473728';

 

2. 

测试sql,获取json字符串中第一组数据(数组下标0开始)的count字段值

select json_extract('[{"count":3000,"eleTypeCode":"ARTICLE_PV","executedCount":0,"occupiedCount":0},{"count":1500,"eleTypeCode":"ARTICLE_UV","executedCount":0,"occupiedCount":0}]', '$[0].count') '文章PV元素';

 

 

案例:

要解析的json数据:

[{"count":3000,"eleTypeCode":"ARTICLE_PV","executedCount":0,"occupiedCount":0},{"count":1500,"eleTypeCode":"ARTICLE_UV","executedCount":0,"occupiedCount":0},{"count":1200,"eleTypeCode":"GUIDE_INTO_SHOP_PV","executedCount":0,"occupiedCount":0},{"count":1000,"eleTypeCode":"GUIDE_INTO_SHOP_UV","executedCount":0,"occupiedCount":0}]

 

 

 

使用 json_extract(字段名,'$.json结构') 解析json,获取json元素值:

查询sql

select 
REPLACE(json_extract(pd_ele_counts, '$[0].eleTypeCode'),'"','') '文章PV元素',json_extract(pd_ele_counts, '$[0].count') '文章PV count',
REPLACE(json_extract(pd_ele_counts, '$[1].eleTypeCode'),'"','') '文章UV元素',json_extract(pd_ele_counts, '$[1].count') '文章UV count',
REPLACE(json_extract(pd_ele_counts, '$[2].eleTypeCode'),'"','') 'shopPV元素',json_extract(pd_ele_counts, '$[2].count') 'shopPV count',
REPLACE(json_extract(pd_ele_counts, '$[3].eleTypeCode'),'"','') 'shopUV元素',json_extract(pd_ele_counts, '$[3].count') 'shopUV count' 
from xp_order where order_no ='OR202012030230477943158211473728';

 

 

 

 

<think> 我们之前讨论的是MySQL中处理字段内容包含通配符(如`%`, `_`)的替换方法,但用户现在的新问题是关于如何使用`json_extract`函数解析多重JSON字符串。这是一个全新的主题,我需要提供关于MySQLJSON函数`json_extract`(或`->`运算符)用于解析嵌套JSON结构的方法。 用户的问题:我想了解如何使用json_extract函数解析多重JSON字符串。 ### 解析步骤: 1. **理解多重JSON结构**:多重JSON通常指嵌套的JSON对象或数组,例如: ```json { "name": "Alice", "contact": { "email": "alice@example.com", "phone": { "home": "123-456", "work": "789-012" } }, "hobbies": ["reading", "travel"] } ``` 2. **使用`json_extract`函数**: - 基本语法:`json_extract(json_doc, path)` - 路径使用`$`表示根,然后使用`.key`访问对象属性,`[index]`访问数组元素(索引从0开始)。 - 示例解析: - 获取name:`json_extract(json_column, '$.name')` - 获取email:`json_extract(json_column, '$.contact.email')` - 获取work电话:`json_extract(json_column, '$.contact.phone.work')` - 获取第一个爱好:`json_extract(json_column, '$.hobbies[0]')` 3. **使用`->`和`->>`运算符**(MySQL 5.7+): - `->`:等价于`json_extract`,返回JSON类型。 - `->>`:先使用`json_extract`,然后对结果执行`json_unquote`,返回字符串(去除引号)。 - 示例: - `json_column->'$.name'` 返回带引号的字符串(如果name是字符串) - `json_column->>'$.name'` 返回不带引号的字符串 4. **处理数组的多重嵌套**: - 提取整个数组:`json_extract(json_column, '$.hobbies')` - 提取数组中的特定元素:`json_extract(json_column, '$.hobbies[1]')`(第二个元素) - 使用`json_table`(MySQL 8.0+)将数组展开为多行(需要MySQL 8.0以上版本) 5. **示例查询**: 假设表名为`users`,JSON列名为`profile`,存储上述示例JSON。 - 查询所有人的名字和邮箱: ```sql SELECT json_extract(profile, '$.name') AS name, json_extract(profile, '$.contact.email') AS email FROM users; ``` 或者: ```sql SELECT profile->>'$.name' AS name, profile->>'$.contact.email' AS email FROM users; ``` - 查询第一个爱好(注意:如果数组为空,返回NULL): ```sql SELECT profile->>'$.hobbies[0]' AS first_hobby FROM users; ``` 6. **处理多层嵌套对象**: 要获取work电话: ```sql SELECT profile->>'$.contact.phone.work' AS work_phone FROM users; ``` 7. **注意事项**: - **路径区分大小写**:JSON中的键名是区分大小写的。 - **路径不存在**:如果路径不存在,返回NULL。 - **数组越界**:如果数组索引超出范围,返回NULL。 - **性能**:在JSON列上使用函数会导致无法使用索引,除非使用生成列(generated column)并创建索引。 8. **MySQL 8.0增强**: - `json_table`函数:将JSON数组转换为关系表(需要MySQL 8.0+)。 - 示例:展开hobbies数组 ```sql SELECT user_id, hobby FROM users, JSON_TABLE(profile->'$.hobbies', '$[*]' COLUMNS (hobby VARCHAR(20) PATH '$')) AS jt; ``` ### 完整示例 #### 创建表和插入数据 ```sql CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, profile JSON ); INSERT INTO users (profile) VALUES ('{ "name": "Alice", "contact": { "email": "alice@example.com", "phone": { "home": "123-456", "work": "789-012" } }, "hobbies": ["reading", "travel"] }'), ('{ "name": "Bob", "contact": { "email": "bob@example.com", "phone": { "home": "111-222" } }, "hobbies": ["sports", "music", "cooking"] }'); ``` #### 查询示例 1. 提取所有用户的姓名和工作电话(如果不存在则返回NULL): ```sql SELECT profile->>'$.name' AS name, profile->>'$.contact.phone.work' AS work_phone FROM users; ``` 结果: | name | work_phone | |-------|------------| | Alice | 789-012 | | Bob | NULL | 2. 提取第一个爱好(使用`json_extract`): ```sql SELECT json_extract(profile, '$.name') AS name, json_extract(profile, '$.hobbies[0]') AS first_hobby FROM users; ``` 结果(注意:返回的hobby是带引号的字符串): | name | first_hobby | |-------|-------------| | Alice | "reading" | | Bob | "sports" | 3. 使用`->>`去掉引号: ```sql SELECT profile->>'$.name' AS name, profile->>'$.hobbies[0]' AS first_hobby FROM users; ``` 结果: | name | first_hobby | |-------|-------------| | Alice | reading | | Bob | sports | 4. 展开所有爱好(MySQL 8.0+): ```sql SELECT profile->>'$.name' AS name, jt.hobby FROM users, JSON_TABLE(profile->'$.hobbies', '$[*]' COLUMNS (hobby VARCHAR(20) PATH '$') ) AS jt; ``` 结果: | name | hobby | |-------|---------| | Alice | reading | | Alice | travel | | Bob | sports | | Bob | music | | Bob | cooking | ### 常见问题解决 - **路径错误**:确保路径拼写正确,包括大小写和嵌套层级。 - **转义特殊字符**:如果键名包含特殊字符(如空格、点等),使用双引号包裹并转义,例如:`$."key with space"`。 - **处理数组长度**:使用`json_length`函数获取数组长度。 ### 相关问题 §§相关问题§§ 1. 如何在MySQL中更新JSON字段中的特定值? 2. 如何检查JSON字段中是否存在某个键? 3. MySQL 8.0的JSON_TABLE函数如何使用? 4. 如何为JSON字段中的嵌套键创建索引? </think> ### 使用 `json_extract` 解析多重 JSON 字符串的方法 在 MySQL解析多重嵌套的 JSON 数据(如对象嵌套对象、对象嵌套数组等),需通过 **JSON Path 表达式**逐层访问嵌套结构。以下是详细操作指南: --- ### 一、核心语法 ```sql -- 基本格式 json_extract(json_doc, '$.顶级键.嵌套键[数组索引]') -- 简写运算符 (MySQL 5.7+) json_doc->'$.路径' -- 返回 JSON 类型 json_doc->>'$.路径' -- 返回字符串类型(自动去除引号) ``` --- ### 二、典型场景解析示例 #### 1. **对象嵌套对象** ```json { "user": { "name": "Alice", "contact": { "email": "alice@example.com", "phones": ["123-4567", "789-0123"] } } } ``` **提取深层字段:** ```sql SELECT json_extract(data, '$.user.name') AS name, -- "Alice" data->'$.user.contact.email' AS email, -- "alice@example.com" data->>'$.user.contact.phones[0]' AS phone -- 123-4567(无引号) FROM json_table; ``` #### 2. **数组嵌套对象** ```json { "orders": [ {"id": 101, "items": [{"name": "Book", "price": 15}]}, {"id": 102, "items": [{"name": "Pen", "price": 2}]} ] } ``` **提取数组中的嵌套字段:** ```sql SELECT json_extract(data, '$.orders[0].id') AS first_order_id, -- 101 data->'$.orders[1].items[0].name' AS second_item_name -- "Pen" FROM json_table; ``` #### 3. **动态路径解析** 若键名包含特殊字符(如空格、横杠)或需拼接路径: ```sql -- 用双引号包裹特殊键名 SELECT json_extract(data, '$."user-info"."full-name"') FROM json_table; -- 拼接路径 (MySQL 8.0+) SET @path = CONCAT('$.orders[', @index, '].id'); SELECT json_extract(data, @path) FROM json_table; ``` --- ### 三、处理多重 JSON 的实用技巧 1. **展开 JSON 数组 → 多行记录** 使用 `JSON_TABLE()` (MySQL 8.0+) 将数组转换为关系表: ```sql SELECT order_id, item_name FROM json_table, JSON_TABLE( data->'$.orders', '$[*]' COLUMNS ( order_id INT PATH '$.id', NESTED PATH '$.items[*]' COLUMNS ( item_name VARCHAR(20) PATH '$.name' ) ) ) AS jt; ``` **输出:** | order_id | item_name | |----------|-----------| | 101 | Book | | 102 | Pen | 2. **检查路径是否存在** 避免 NULL 值导致的错误: ```sql SELECT json_contains_path(data, 'one', '$.user.contact.email') AS has_email, data->'$.user.contact.email' AS email FROM json_table; ``` 3. **合并多重解析结果** 提取多个字段组合为新 JSON: ```sql SELECT JSON_OBJECT( 'user_name', data->>'$.user.name', 'first_phone', data->>'$.user.contact.phones[0]' ) AS user_summary FROM json_table; ``` --- ### 四、性能优化建议 1. **路径索引加速** 对频繁访问的路径创建虚拟列并加索引: ```sql ALTER TABLE json_table ADD COLUMN user_email VARCHAR(50) GENERATED ALWAYS AS (data->>'$.user.contact.email'), ADD INDEX (user_email); ``` 2. **避免全路径扫描** ```sql -- 低效 (全表扫描) SELECT * FROM json_table WHERE json_extract(data, '$.user.name') = 'Alice'; -- 高效 (使用生成列索引) SELECT * FROM json_table WHERE user_email = 'alice@example.com'; ``` 3. **部分 JSON 更新** 修改嵌套值而不重写整个 JSONMySQL 8.0+): ```sql UPDATE json_table SET data = JSON_SET(data, '$.user.contact.email', 'new@email.com') WHERE id = 1; ``` --- ### 五、错误排查 - **路径不存在** → 返回 `NULL` - **类型不匹配** → 用 `CAST(value AS UNSIGNED)` 转换数字 - **语法错误** → 检查键名引号和数组索引(从 `0` 开始) - **特殊字符** → 路径中用双引号包裹键名:`$."key with space"` > 💡 使用前验证路径: > ```sql > SELECT JSON_KEYS(data, '$.user') FROM json_table; -- 列出所有子键 > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值