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 07 MySQL
将图片保存到mysql数据库并展示在前端页面的实现代码
May 02 MySQL
MySQL 覆盖索引的优点
May 19 MySQL
你知道哪几种MYSQL的连接查询
Jun 03 MySQL
MySql 缓存查询原理与缓存监控和索引监控介绍
Jul 02 MySQL
MySQL系列之二 多实例配置
Jul 02 MySQL
MySQL数据库必备之条件查询语句
Oct 15 MySQL
SQL注入篇学习之盲注/宽字节注入
Mar 03 MySQL
MYSQL优化之数据表碎片整理详解
Apr 03 MySQL
MySQL中优化SQL语句的方法(show status、explain分析服务器状态信息)
Apr 09 MySQL
优化Mysql查询的示例
Apr 26 MySQL
深入理解MySQL中MVCC与BufferPool缓存机制
May 25 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/09 PHP
支付宝支付开发――当面付条码支付和扫码支付实例
2016/11/04 PHP
windows下的WAMP环境搭建图文教程(推荐)
2017/07/27 PHP
javascript js cookie的存储,获取和删除
2007/12/29 Javascript
JQuery上传插件Uploadify使用详解及错误处理
2010/04/27 Javascript
再谈querySelector和querySelectorAll的区别与联系
2012/04/20 Javascript
图片上传插件jquery.uploadify详解
2013/11/15 Javascript
jQuery固定浮动侧边栏实现思路及代码
2014/09/28 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
Bootstrap模态框(modal)垂直居中的实例代码
2016/08/18 Javascript
web打印小结
2017/01/11 Javascript
jQuery实现判断上传图片类型和大小的方法示例
2018/04/11 jQuery
微信小程序多音频播放进度条问题
2018/08/28 Javascript
如何制作一个Node命令行图像识别工具
2018/12/12 Javascript
JavaScript设计模式之命令模式实例分析
2019/01/16 Javascript
nodejs中实现用户注册路由功能
2019/05/20 NodeJs
Node.js 路由的实现方法
2019/06/05 Javascript
微信小程序页面上下滚动效果
2020/11/18 Javascript
Vue-cli打包后部署到子目录下的路径问题说明
2020/09/02 Javascript
解决Python中字符串和数字拼接报错的方法
2016/10/23 Python
python 实现一个贴吧图片爬虫的示例
2017/10/12 Python
python安装numpy&安装matplotlib& scipy的教程
2017/11/02 Python
Python爬虫使用代理IP的实现
2019/10/27 Python
利用Python绘制有趣的万圣节南瓜怪效果
2019/10/31 Python
pyCharm 实现关闭代码检查
2020/06/09 Python
灵活运用CSS3特性绘制简易版围棋效果
2016/09/28 HTML / CSS
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
Dillard’s百货官网:Dillards.com
2018/05/26 全球购物
Pretty Little Thing美国:时尚女性服饰
2018/08/27 全球购物
Hotels.com越南:酒店预订
2019/10/29 全球购物
财政局长自荐信范文
2013/12/22 职场文书
上班玩游戏检讨书
2014/02/07 职场文书
农民工预备党员思想汇报
2014/09/14 职场文书
三好学生主要事迹怎么写
2015/11/03 职场文书
python 开心网和豆瓣日记爬取的小爬虫
2021/05/29 Python
彻底弄懂Python中的回调函数(callback)
2022/06/25 Python