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 8.0.24 安装配置方法图文教程
May 12 MySQL
MySQL如何构建数据表索引
May 13 MySQL
详解MySQL连接挂死的原因
May 18 MySQL
详解MySQL集群搭建
May 26 MySQL
MySQL中IF()、IFNULL()、NULLIF()、ISNULL()函数的使用详解
Jun 26 MySQL
MySQL系列之四 SQL语法
Jul 02 MySQL
MySQL去除重叠时间求时间差和的实现
Aug 23 MySQL
Nebula Graph解决风控业务实践
Mar 31 MySQL
提高系统的吞吐量解决数据库重复写入问题
Apr 23 MySQL
MySql数据库触发器使用教程
Jun 01 MySQL
MySQL控制流函数(-if ,elseif,else,case...when)
Jul 07 MySQL
SQLyog的下载、安装、破解、配置教程(MySQL可视化工具安装)
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
解析php中获取系统信息的方法
2013/06/25 PHP
PHP JS Ip地址及域名格式检测代码
2013/09/27 PHP
Thinkphp的volist标签嵌套循环使用教程
2014/07/08 PHP
WordPress中调试缩略图的相关PHP函数使用解析
2016/01/07 PHP
PHP实现Google plus的好友拖拽分组效果
2016/10/21 PHP
统一接口:为FireFox添加IE的方法和属性的js代码
2007/03/25 Javascript
javascript整除实现代码
2010/11/23 Javascript
jQuery创建插件的代码分析
2011/04/14 Javascript
jQuery学习笔记 操作jQuery对象 属性处理
2012/09/19 Javascript
jquery eval解析JSON中的注意点介绍
2013/08/23 Javascript
js自动生成对象的属性示例代码
2013/10/28 Javascript
jquery validate 自定义验证方法介绍 日期验证
2014/02/27 Javascript
jQuery中nextUntil()方法用法实例
2015/01/07 Javascript
微信小程序 选择器(时间,日期,地区)实例详解
2016/11/16 Javascript
在Vue中使用echarts的实例代码(3种图)
2017/07/10 Javascript
Vue项目中引入外部文件的方法(css、js、less)
2017/07/24 Javascript
详解基于vue的移动web app页面缓存解决方案
2017/08/03 Javascript
vue登录以及权限验证相关的实现
2019/10/25 Javascript
js实现登录时记住密码的方法分析
2020/04/05 Javascript
js防抖函数和节流函数使用场景和实现区别示例分析
2020/04/11 Javascript
[54:09]RNG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
利用python模拟实现POST请求提交图片的方法
2017/07/25 Python
Python各类图像库的图片读写方式总结(推荐)
2018/02/23 Python
Python列表推导式与生成器用法分析
2018/08/02 Python
python requests post多层字典的方法
2018/12/27 Python
pygame实现俄罗斯方块游戏(基础篇3)
2019/10/29 Python
Python的pygame安装教程详解
2020/02/10 Python
Python3 Click模块的使用方法详解
2020/02/12 Python
Melijoe美国官网:法国奢侈童装购物网站
2017/04/19 全球购物
师范毕业生个人求职信
2013/12/09 职场文书
青奥会口号
2014/06/12 职场文书
社区志愿者活动总结
2014/06/26 职场文书
秋季运动会演讲稿
2014/09/16 职场文书
《活见鬼》教学反思
2016/02/24 职场文书
PyQt5 QThread倒计时功能的实现代码
2021/04/02 Python
JS前端宏任务微任务及Event Loop使用详解
2022/07/23 Javascript