首页 > 数据库 >MySQL——处理JSON类型的数据

MySQL——处理JSON类型的数据

时间:2023-09-25 14:36:05浏览次数:83  
标签:-- testDemo JSON 键值 MySQL 类型 cpu SELECT

MySQL对JSON类型数据的处理

参考视频:快速学习MySQL 8 JSON
注意,本文的键名也可以叫key,键值也可以叫value,意思是一样的

1. 字符串查询:JSON_EXTRACT

假设我们有一个表叫做testDemo,其中有一个字段叫做details,类型为JSON,他的数据结构如下,我们就以这个结构为例(这是个例子,假设有很多行数据,他们的detail都是这样的结构,键名相同,但是键值不同):

{
	cpu: "A100",
	system: "Windows10",
	ram: "8G",
	disk: "500G,SSD"
}

描述:按要求在JSON字符串种提取某个键名的值(主要用于键值对的JSON数据),接受两个参数:JSON_EXTRACT(目标字段名, 匹配的键名)


①(Map)获取JSON内指定键名的键值,并且把查询到的字段值拼接在表后:

-- 写法一
SELECT *, JSON_EXTRACT(detail, '$.cpu') AS CPU FROM testDemo;
-- 从testDemo中获取字段为detail的字符串数据,并且解析其中键名为cpu的数据,拼接在完整查询表的后面,AS是指定查询拼接的这个字段的名字
-- 写法二
SELECT detail->'$.cpu' FROM testDemo;
-- 这样查询只会显示cpu字段的值,也就是不会拼接在数据表后,而是单独一个字段

拼接的样子如下,如果不拼接,就是只有CPU这一个字段的他下面的值:
image
这里表的本身只有id,name,price,colors,details四个字段,第五个字段CPU是查询后拼接在查询表的最后,而不是表原本有的字段。

不拼接是这样:
image
如果你需要纯粹的字符串(也就是不要双引号,可以这样写)

SELECT JSON_UNQUOTE(detail->'$.cpu') FROM testDemo;
-- 或者这样写
SELECT detail->>'$.cpu' FROM testDemo;
-- 同理①如果按下面这样写,那么最后的cpu字段的结果也不会有双引号
SELECT *, detail->>'$.cpu' FROM testDemo;

结果就是:
image
image



②(Map)获取JSON内指定键名的符合条件的键值,并且把查询到的字段值拼接在表后:

SELECT *, JSON_EXTRACT(detail, '$.cpu') AS CPU FROM testDemo WHERE JSON_EXTRACT(detail, '$.cpu') = 'A100';
-- 同①类似,不过这里要求获取的是键名为cpu键值为A100的数据,同样会拼接到表后




③(Map)获取JSON内的数组:
image
第一个是获取键名为c的全部元素,,输出是:[3,4,5]
第二个是获取键名为c,索引为1和2的元素(数组索引从0开始),输出是:[4,5]
第三个是获取键名为c,索引为倒数第二个的元素,输出为:4


2. 数组查询:MEMBER OF

image

SELECT * FROM testDemo WHERE 'white' MEMBER OF (color);
-- 查询testDemo表所有字段,条件是字段color(JSON类型,存储了数组)JSON数组中有white这个元素的存在



3. 键值对筛选:JSON_CONTAINS(使用JSON_OBJECT组成键值对形式条件)

SELECT * FROM testDemo WHERE JSON_CONTAINS(details, JSON_OBJECT('system', 'iOS'));
-- 查询testDemo表全部字段,条件是details(JSON类型)字段,键名为system,键值为iOS的数据

image


4. 判断是否存在某个键名:JSON_CONTAINS_PATH

SELECT * FROM testDemo WHERE JSON_CONTAINS_PATH(details, 'one|all', '$.cpu');
-- 查询testDemo表全部字段,条件是details(JSON类型)字段,中含有一个|全部包含,键名为cpu
-- 当然你可以写满足多条,选用one就是有一个满足就返回,all就是要全部满足才返回,例如:
SELECT * FROM testDemo WHERE JSON_CONTAINS_PATH(details, 'one|all', '$.cpu', '$.ram', '$.disk');



SELECT details, JSON_SEARCH(details, "one|all", 'Kirin 980') FROM testDemo;
-- 查询 testDemo表中,details(JSON类型)字段的字符串,满足一个/全部满足,键值为Kirin 980的数据,只展示details列,把查询结果拼接在这个列后,没有就显示null,使用all的话,返回结果是一个数组类型

image


6. 修改JSON数据:JSON_SET/JSON_INSERT/JSON_REPLACE/JSON_REMOVE

image
让我们一个一个看:


1.首先SET是设置了一个JSON数组字符串(数组第一个元素索引是0),用于后续的操作


2.JSON_SET,用于修改/添加元素(有就是覆盖修改,没有就是新增)
例如此处:
他选择了我们设置好的JSON字符串@j,对第二个元素(也就是b那个键值对)的值(数组)的第1个元素(索引为0)修改为1【因为已经存在,就修改它】;
再对@j的第三个元素(数组)的第三个元素修改为2【不存在,增加它】;
结果输出为:image

3.JSON_INSERT,插入数据,没有就新增,有就跳过
例如此处:
对@j的第二个元素的键名为b的值的,第一个元素,插入1【由于已经存在值,跳过插入】;
再对@j的第三个元素,的第三个元素插入2;
结果输出为:image

4.JSON_REPLACE,替换,有才替换,没有就不替换
例如此处:
对@j的第二个元素的键名为b的值的,第一个元素,替换为1;
再对@j的第三个元素,的第三个元素替换为2【由于不存在第三个元素,因此跳过替换】;
结果输出为:image

5.JSON_REMOVE,删除,数据不存在会被跳过删除
对@j的第三个元素进行删除(数组);再对第二个元素键名为b的第二个元素删除(删除false);再次对第二个元素键名为b的第二个元素删除【由于已经不存在,跳过删除】;
结果输出为:image

7. 聚合查询:JSON_ARRAYAGG(类似于GROUP_CONCAT)

我们以这个表为例:
image
我们想分组查询出价格【主】和产品名字(价格只展示一次,但是可以有不同的名字)

SELECT GROUP_CONCAT(name), price FROM testDemo GROUP BY price;
SELECT JSON_ARRAYAGG(name), price FROM testDemo GROUP BY price;

第一行效果是:image
第二行是:image
区别在于第一个是直接打印值,第二个是输出成一个JSON字符串。


8. 获取一个JSON键值对字符串的全部键名:JSON_KEYS

我们以这个表为例:
image
要获取details的JSON键值对字符串的全部键值:

SELECT JSON_KEYS(details) FROM testDemo;

输出为:image

9. 获取一个JSON键值对字符串有多少个键名:JSON_LENGTH

image

SELECT JSON_LENGTH(details) FROM testDemo;

输出:image

10. 验证一个JSON是否合法:JSON_VALID

SELECT JSON_VALID(你的json字符串);
-- 合法输出1,否则输出0



11. 格式化JSON:JSON_PRETTY

SELECT JSON_PRETTY(你的json字符串);
-- 例如:
SELECT JSON_PRETTY({["cpu":"骁龙865","system":"android","storage":"128G"},
{"cpu": "A8", "system" : "ios", "storage" :"256G"}]');

输出结果为:image


12. 纵向改横向(输出类似于表格的形式):JSON_TABLE

SELECT * FROM JSON_TABLE(
	'[{"cpu":"骁龙865","system" :"android","storage":"128G"},
	{"cpu": "A8", "system" :"ios", "storage": "256G"}]",
		"$[*]" COLUMNS(
			CPU VARCHAR(100) PATH "$.cpu",
			`System` VARCHAR(100) PATH "$.system",
			`Storage` VARCHAR(100) PATH "$.storage"
		)
) AS JT;
-- 此处由于system和storage是MYSQL的保留关键字,因此使用``进行转义

输出结果是:image


13. 自定义JSON数据验证:JSON_SCHEMA_VALIDATION_REPORT

用法:

SELECT JSON_SCHEMA_VALIDATION_REPORT(自定义的校验规则,要被校验的JSON字符串)

如果通过,会返回{"valid": true}


否则返回:{"valid": false, "reason": "原因", "shema-location": "相关的自定义校验规则出现失败的位置","document-location": "被校验的JSON字符串出现失败的位置","shema-failed-keyword": "导致出现失败的条件"}
例子:

SET @schema = '{
	"id": "http://json-schema.org/geo",
	"$schema": "http://json-schema.org/draft-04/schema#",
	"description": "A geographical coordinate",
	"type": "object",
	"properties": {
		"latitude": {
			"type": "number",
			"minimum": -90,
			"maximum": 90
		},
		"longitude": {
			"type": "number",
			"minimum": -180,
			"maximum": 180
		}
	},
	"required": ["latitude", "longitude"]
}';
-- properties内规定了校验规则,接受指定两个键名,值要求为数字类型,且有不同的取值范围,required指定哪些键名是必填的

SET @document = '{
	"latitude": 63.444697,
	"longitude": 110.445118.
}'
SELECT JSON_SCHEMA_VALIDATION_REPORT(@schema, @document)

最终结果输出:image

标签:--,testDemo,JSON,键值,MySQL,类型,cpu,SELECT
From: https://www.cnblogs.com/MorningMaple/p/17726974.html

相关文章

  • MySQL 索引、事务与存储引擎
    MySQL索引、事务与存储引擎---MySQL索引---1.索引的概念●索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于C语言的链表通过指针指向数据记录的内存地址)。●使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数......
  • mysql常用函数
    1、AVG():返回平均值2、COUNT():返回行数3、FIRST():返回第一个记录的值4、LAST():返回最后一个记录的值5、MAX():返回最大值6、MIN():返回最小值7、SUM():返回总和8、UCASE():将某个字段转换为大写9、LCASE():将某个字段转换为小写12、ROUND():对某个数值字段进行指定小数位数的四......
  • 14.JSON之间的相互转换
    Javascript中任何支持的类型都可以转换为JSON字符串对象{}数组【】所有的键值对key;valuevarasd={name:'猴王',age:123,nl:12234123}//对象转化为JSON字符串varaaa=JSON.stringify(asd);//JSON字符串转化为对象varabc=JSON.parse('{......
  • mysql8安装踩坑记
    背景:已安装mysql5.7版本问题一:默认的3306端口被占用进入mysql5.7的my.ini文件,更改port为3307或者其他未被占用的端口问题二:Install/RemoveoftheServiceDenied!cmd用管理员的身份运行,执行mysqld--installmysql8.0.34(拿版本号取得别名)问题三:启动MySQL服务时出......
  • java中mysql索引过多导致查询的时间不稳定
    在Java中,MySQL索引过多可能导致查询时间不稳定的情况确实存在。尽管索引可以加速查询,但是索引也会带来额外的维护成本和存储开销。当数据库表中存在过多的索引时,可能会导致以下几个问题:查询优化器选择困难:当有多个索引可供选择时,查询优化器需要评估每个索引的成本和选择最佳的索引......
  • java数据类型
    Java虚拟机中,数据装型及其运算都是由Java虚拟机规范严格定义的。数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位......
  • MySQL实战实战系列 06 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
    今天我要跟你聊聊MySQL的锁。数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。而锁就是用来实现这些访问规则的重要数据结构。 根据加锁的范围,MySQL里面的锁大致可以分成全局锁、表级锁和行锁三类。今天这......
  • Mysql数据库定时备份到OSS
    背景mysql运行在Docker中,计划每天定时备份数据并存储到阿里云OSS。其中用到了定时任务crontab、云存储管理rclone、shell脚本部署脚本#创建目录mkdir-p~/taskcd~/task#创建主备份脚本touchbackup_main.sh#创建mysql备份脚本,这个后面要传到运行mysql的docker容器to......
  • mysql 查询时额外查询一个index列,类似sqlserver的ROW_NUMBER()
    --创建临时表CREATETEMPORARYTABLEtemp1AS(SELECT(@rowindex:=@rowindex+1)ASrowindex,a.city_id,b.nameas'city_name',a.dept_name,a.final_pointFROMaqjd_assessment_deptaJOINsys_citybona.city_id=b.idJOIN(SELECT(@rowindex:=......
  • C#中使用Newtonsoft.Charp实现Json对象序列化与反序列化
    场景C#中使用Newtonsoft.Json实现对Json字符串的解析:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/105795048上面讲的对JSON字符串进行解析,实际就是JSON对象的反序列化。在与第三方进行交互时常需要封装对象,存储各种属性消息,然后将对象序列化为json字符串并进......