MySQL对JSON类型字段数据进行提取和查询的实现

作者:慕城南风 时间:2024-01-23 02:48:54 

前言

昨天上线后通过系统报警发现了一个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格式中查询并返回符合条件的节点
这是一个非常强大的函数

来源:https://blog.csdn.net/lovedingd/article/details/124300450

标签:MySQL,JSON,字段,提取,查询
0
投稿

猜你喜欢

  • javascript实现获取浏览器版本、操作系统类型

    2024-05-13 10:36:21
  • MSSQL报错:参数数据类型 text 对于 replace 函数的参数 1 无效的解决办法

    2024-01-27 09:04:15
  • python中list常用操作实例详解

    2021-05-13 02:33:25
  • Python实现将wav转amr,并转换成hex数组

    2023-06-29 08:18:59
  • python中namedtuple函数的用法解析

    2023-08-22 11:03:24
  • 一篇文章带你学习Python3的高级特性(2)

    2021-03-29 13:56:40
  • go语言的工作空间和GOPATH环境变量介绍

    2024-05-09 10:11:34
  • vue文件树组件使用详解

    2024-05-09 09:53:52
  • javascript attachEvent绑定多个事件执行顺序问题

    2024-04-08 10:53:06
  • pandas数据预处理之dataframe的groupby操作方法

    2022-07-07 19:27:56
  • 关于浮动的前世今生

    2009-08-19 18:51:00
  • Javascript获取表单名称(name)的方法

    2024-06-07 15:25:45
  • python类共享变量操作

    2021-10-21 02:16:32
  • python制作图片缩略图

    2023-08-23 18:49:32
  • 详解用node-images 打造简易图片服务器

    2024-05-11 10:13:23
  • C#从数据库读取图片并保存的两种方法

    2024-01-12 14:39:22
  • Python机器学习库scikit-learn入门开发示例

    2022-10-15 11:40:24
  • mysql日志文件在哪 如何修改MySQL日志文件位置

    2024-01-22 22:09:14
  • 解决Mac下使用python的坑

    2021-02-26 21:47:38
  • python非标准时间的转换

    2022-04-12 17:37:52
  • asp之家 网络编程 m.aspxhome.com