MySQL提取JSON字段数据实现查询


Posted in MySQL onApril 22, 2022

前言

昨天上线后通过系统报警发现了一个bug,于是紧急进行了回滚操作,但是期间有用户下单,数据产生了影响,因此需要排查影响了哪些订单,并对数据进行修复。

1. 问题现象

由于bug导致了订单表的customer_extra_info字段的hasFreightInsurance误更新成了“是”,因此需要查询回滚前一共有多少被误更新为“是”的订单,如下图:

MySQL提取JSON字段数据实现查询

于是查看订单表中customer_extra_info字段类型发现是JSON类型的

MySQL提取JSON字段数据实现查询

2. 解决方案

查询资料发现mysql5.7以后提供了一种新的字段格式-json。

对JSON类型的数据MySQL提供了相关的查询操作。

先给出查询SQL,后面在介绍MySQL对JSON类型字段的查询操作

SELECT
	* 
FROM
	( SELECT id, customer_extra_info -> '$.hasFreightInsurance' AS Insurance FROM oms_order_list WHERE project_id = 1 AND update_time > '2022-04-15 16:30:17' ) t 
WHERE
	JSON_CONTAINS ( Insurance, JSON_OBJECT ( "value", "是" ) )

3. JSON数据查询

3.1 一般基础查询操作

1、使用 json字段名->’$.json属性’ 进行查询条件

SELECT
	id,
	customer_extra_info
FROM
	oms_order_list 
WHERE
	project_id = 1 
	AND update_time > '2022-04-15 16:30:17'
	AND customer_extra_info -> '$.maxClaimAmount'=10

查询结果如下:

MySQL提取JSON字段数据实现查询

 2、关联表查询

json字段也支持关联表的查询,这里只写出使用方法,不做实例展示。其中deptLeaderId和id分别是dept,dept_leader两个表中的关联字段。

SELECT * from dept,dept_leader WHERE dept.json_value->'$.deptLeaderId'=dept_leader.json_value->'$.id' ;

3.2 一般函数查询操作

写到这里大家都发现了,我们查询的json都是整条json数据,这样看起来不是很方便,那么如果我们只想看json中的某个字段怎么办?

这样就引入了我们的第一个函数:json_extract(字段名,json字段名)

在详细介绍用法之前我们可以看看官网的函数介绍:

MySQL提取JSON字段数据实现查询

 咱们可以看到官网介绍json_extract()这个函数很详细:Return data from JSON document

从json中返回字段

1、函数 json_extract():从json中返回想要的字段

用法:json_extract(字段名,$.json字段名)
实例:

SELECT
	id,
	json_extract ( customer_extra_info, '$.hasFreightInsurance' ) AS hasFreightInsurance 
FROM
	oms_order_list 
WHERE
	project_id = 1 
	AND update_time > '2022-04-15 16:30:17'

查询结果如下:

MySQL提取JSON字段数据实现查询

2、函数JSON_CONTAINS():JSON格式数据是否在字段中包含特定对象 

用法: JSON_CONTAINS(target, candidate[, path])
实例:

SELECT
	id,
	customer_extra_info 
FROM
	oms_order_list 
WHERE
	project_id = 1 
	AND update_time > '2022-04-15 16:30:17' 
	AND JSON_CONTAINS ( customer_extra_info, JSON_OBJECT ( "maxClaimAmount", 10 ) )

查询结果如下:

MySQL提取JSON字段数据实现查询

3、函数JSON_OBJECT():将一个键值对列表转换成json对象 

比如我们想查询某个对象里面的值等于多少

我们可以看到hasFreightInsurance中还有一个对象,里面还有name和value两个属性字段,那么我们应该怎么查询value=否的订单呢。

用法:JSON_OBJECT([key, val[, key, val] …])
实例:

SELECT
	* 
FROM
	( SELECT id, customer_extra_info -> '$.hasFreightInsurance' AS Insurance FROM oms_order_list WHERE project_id = 1 AND update_time > '2022-04-15 16:30:17' ) t 
WHERE
	JSON_CONTAINS ( Insurance, JSON_OBJECT ( "value", "否" ) )

查询结果如下:

MySQL提取JSON字段数据实现查询

4、函数JSON_ARRAY():创建JSON数组

​用法:JSON_ARRAY([val[, val] …])

实例:我们要查询deptName包含1的数据

SELECT
	id,
	customer_extra_info 
FROM
	oms_order_list 
WHERE
	project_id = 1 
	AND update_time > '2022-04-15 16:30:17' 
	AND JSON_CONTAINS ( customer_extra_info -> '$.deptName', JSON_ARRAY ( "1" ) )

查询结果如下:

MySQL提取JSON字段数据实现查询

5、函数JSON_TYPE():查询某个json字段属性类型

用法:JSON_TYPE(json_val)
事例:比如我们想查询deptName的字段属性是什么

SELECT
	id,
	customer_extra_info -> '$.deptName',
	JSON_TYPE ( customer_extra_info -> '$.deptName' ),
	customer_extra_info -> '$.hasFreightInsurance',
	JSON_TYPE ( customer_extra_info -> '$.hasFreightInsurance' ) 
FROM
	oms_order_list 
WHERE
	project_id = 1 
	AND update_time > '2022-04-15 16:30:17'

查询结果如下:

MySQL提取JSON字段数据实现查询

6、函数JSON_EXTRACT() :从JSON文档返回数据 

这也是我们开发中会经常用到的一个函数

SELECT
	* 
FROM
	oms_order_list 
WHERE
	project_id = 1 
	AND update_time > '2022-04-15 16:30:17' 
	AND JSON_CONTAINS ( JSON_EXTRACT ( customer_extra_info, '$.hasFreightInsurance' ), JSON_OBJECT ( "value", "否" ) )

 查询结果如下:

MySQL提取JSON字段数据实现查询

7、函数JSON_KEYS() :JSON文档中的键数组

 用法:JSON_KEYS(json_value)

实例:比如我们想查询json格式数据中的所有key

SELECT
	id,
	JSON_KEYS ( customer_extra_info ) 
FROM
	oms_order_list 
WHERE
	project_id = 1 
	AND update_time > '2022-04-15 16:30:17'

 查询结果如下:

MySQL提取JSON字段数据实现查询

4. JSON数据新增更新删除

接下来的3种函数都是新增数据类型的:
JSON_SET(json_doc, path, val[, path, val] …)
JSON_INSERT(json_doc, path, val[, path, val] …)
JSON_REPLACE(json_doc, path, val[, path, val] …)

1、函数JSON_SET() :将数据插入JSON格式中,有key则替换,无key则新增
这也是我们开发过程中经常会用到的一个函数

用法:JSON_SET(json_doc, path, val[, path, val] …)

实例:比如我们想针对id=2的数据新增一组:newData:新增的数据,修改deptName为新增的部门1
sql语句如下:

update dept set json_value=JSON_SET('{"deptName": "部门2", "deptId": "2", "deptLeaderId": "4"}','$.deptName','新增的部门1','$.newData','新增的数据') WHERE id=2;
 
select * from dept WHERE id =2

结果:

MySQL提取JSON字段数据实现查询

注意:json_doc如果不带这个单元格之前的值,之前的值是会被新值覆盖的,比如我们如果更新的语句换成:

update dept set json_value=JSON_SET('{"a":"1","b":"2"}','$.deptName','新增的部门1','$.newData','新增的数据') WHERE id=2

我们可以看到这里json_doc是{“a”:“1”,“b”:“2”},这样的话会把之前的单元格值覆盖后再新增/覆盖这个单元格字段

结果:

MySQL提取JSON字段数据实现查询

2、函数JSON_INSERT():插入值(往json中插入新值,但不替换已经存在的旧值)
用法:JSON_INSERT(json_doc, path, val[, path, val] …)

 实例:

UPDATE dept set json_value=JSON_INSERT('{"a": "1", "b": "2"}', '$.deptName', '新增的部门2','$.newData2','新增的数据2') 
WHERE id=2

结果:

MySQL提取JSON字段数据实现查询

 我们可以看到由于json_doc变化将之前的值覆盖了,新增了deptName和newData2.
如果我们再执行以下刚才的那个sql,只是换了value,我们会看到里面的key值不会发生变化。
因为这个函数只负责往json中插入新值,但不替换已经存在的旧值。

3、函数JSON_REPLACE()
用法:JSON_REPLACE(json_doc, path, val[, path, val] …)

用例:
如果我们要更新id=2数据中newData2的值为:更新的数据2

sql语句如下:

UPDATE dept set json_value=JSON_REPLACE('{"a": "1", "b": "2", "deptName": "新增的部门2", "newData2": "新增的数据2"}', '$.newData2', '更新的数据2') WHERE id =2;
 
select * from dept WHERE id =2

结果:

MySQL提取JSON字段数据实现查询

4、函数JSON_REMOVE() :从JSON文档中删除数据
用法:JSON_REMOVE(json_doc, path[, path] …)

举例:删除key为a的字段。

UPDATE dept set json_value=JSON_REMOVE('{"a": "1", "b": "2", "deptName": "新增的部门2", "newData2": "更新的数据2"}','$.a') WHERE id =2;

结果:

MySQL提取JSON字段数据实现查询

5、函数JSON_SEARCH() :用于在json格式中查询并返回符合条件的节点
这是一个非常强大的函数

到此这篇关于MySQL对JSON类型字段数据进行提取和查询的实现的文章就介绍到这了!


Tags in this post...

MySQL 相关文章推荐
Mysql 性能监控及调优
Apr 06 MySQL
mysql批量新增和存储的方法实例
Apr 07 MySQL
MySQL 查询速度慢的原因
May 25 MySQL
Mysql 用户权限管理实现
May 25 MySQL
MySql 8.0及对应驱动包匹配的注意点说明
Jun 23 MySQL
MySQL系列之七 MySQL存储引擎
Jul 02 MySQL
SQL基础的查询语句
Nov 11 MySQL
一文弄懂MySQL索引创建原则
Feb 28 MySQL
浅谈MySQL中的六种日志
Mar 23 MySQL
mysqldump进行数据备份详解
Jul 15 MySQL
面试官问我Mysql的存储引擎了解多少
Aug 05 MySQL
MySQL中dd::columns表结构转table过程及应用详解
Sep 23 MySQL
mysql使用FIND_IN_SET和group_concat两个方法查询上下级机构
Apr 20 #MySQL
在MySQL中你成功的避开了所有索引
Apr 20 #MySQL
mysql中如何用命令创建联合唯一索引
Apr 20 #MySQL
mysql 8.0.27 绿色解压版安装教程及配置方法
MySQL去除密码登录告警的方法
Apr 20 #MySQL
MySQL数据库事务的四大特性
Windows 64位 安装 mysql 8.0.28 图文教程
You might like
探讨file_get_contents与curl效率及稳定性的分析
2013/06/06 PHP
php读取目录所有文件信息dir示例
2014/03/18 PHP
推荐25款php中非常有用的类库
2014/09/29 PHP
PHP strip_tags() 去字符串中的 HTML、XML 以及 PHP 标签的函数
2016/05/22 PHP
function, new function, new Function之间的区别
2007/03/08 Javascript
jQuery 1.2.x 升? 1.3.x 注意事项
2009/05/06 Javascript
JQuery从头学起第三讲
2010/07/06 Javascript
js调用后台、后台调用前台等方法总结
2014/04/17 Javascript
jQuery源码分析之jQuery.fn.each与jQuery.each用法
2015/01/23 Javascript
浅谈javascript中this在事件中的应用
2015/02/15 Javascript
jQuery基础知识点总结(必看)
2016/05/31 Javascript
JQuery和PHP结合实现动态进度条上传显示
2016/11/23 Javascript
jquery select2的使用心得(推荐)
2016/12/04 Javascript
axios的拦截请求与响应方法
2018/08/11 Javascript
vue-cli系列之vue-cli-service整体架构浅析
2019/01/14 Javascript
[02:57]DOTA2亚洲邀请赛 SECRET战队出场宣传片
2015/02/07 DOTA
Django集成百度富文本编辑器uEditor攻略
2014/07/04 Python
python脚本作为Windows服务启动代码详解
2018/02/11 Python
TensorFlow模型保存和提取的方法
2018/03/08 Python
Python中staticmethod和classmethod的作用与区别
2018/10/11 Python
python如何制作英文字典
2019/06/25 Python
tensorflow将图片保存为tfrecord和tfrecord的读取方式
2020/02/17 Python
django 链接多个数据库 并使用原生sql实现
2020/03/28 Python
python 决策树算法的实现
2020/10/09 Python
Topshop法国官网:英国快速时尚品牌
2018/04/08 全球购物
护理专科毕业推荐信
2013/11/10 职场文书
群教班子对照检查材料
2014/08/26 职场文书
英语四级考试作弊检讨书
2014/09/29 职场文书
2014年学习部工作总结
2014/11/12 职场文书
2014年学校德育工作总结
2014/12/05 职场文书
诚信承诺书
2015/01/19 职场文书
2015学校年度工作总结
2015/05/11 职场文书
2015年公司行政后勤工作总结
2015/05/20 职场文书
golang gopm get -g -v 无法获取第三方库的解决方案
2021/05/05 Golang
电脑无法安装Windows 11怎么办?无法安装Win11的解决方法
2021/11/21 数码科技
JavaScript 与 TypeScript之间的联系
2021/11/27 Javascript