SQL进阶:如何把字段中的键值对转为JSON格式?

JSON

一、问题描述

假如某张表的某列是键值对数据,如何把这个键值对转为json格式,数据如下所示

dynasty value
唐朝 唐太宗:李世民;唐高宗:李治;唐玄宗:李隆基;...
汉朝 汉高祖:刘邦;汉文帝:刘恒;汉景帝:刘启;汉武帝:'刘彻';...

需要转成下面这种格式

dynasty value
唐朝 {"key":"唐太宗","value":"李世民","order":"1"},{"key":"唐高宗","value":"李治","order":"2"},{"key":"唐玄宗","value":"李隆基","order":"3"}...
汉朝 {"key":"汉高祖","value":"刘邦","order":"1"},{"key":"汉文帝","value":"刘恒","order":"2"},{"key":"汉景帝","value":"刘启","order":"3"},{"key":"汉武帝","value":"刘彻","order":"2"}...

二、ORACLE

<一>、键值对拆分(REGEXP_SUBSTR)

sql 复制代码
with split_data as (
	select 
			dynasty,
	 		regexp_substr(value,'[^;]+',1,level) as part,
			level as part_num
	 from table
  connect by 
  	regexp_substr(value,'[^;]+',1,level) is not null
)
	select dynasty,
	       part_num,
	       regexp_substr(part,'[^;]+',1,1) as key,
	       regexp_substr(part,'[^;]+',1,2) as value
      from split_data

执行完就是如下形式

dynasty part_num key value
唐朝 1 唐太宗 李世民
唐朝 2 唐高宗 李治
唐朝 3 唐玄宗 李隆基
汉朝 1 汉高祖 刘邦
汉朝 2 汉文帝 刘恒
汉朝 3 汉景帝 刘启
汉朝 4 汉武帝 刘彻
...

<二>、转为JSON

转为JSON有现成的转JSON函数,完整代码如下

sql 复制代码
with split_data as (
	select 
	        dynasty,
	 		regexp_substr(value,'[^;]+',1,level) as part,
			level as part_num
	 from table
  connect by 
  	regexp_substr(value,'[^;]+',1,level) is not null
),key_value_pairs as (
	select dynasty,
	       part_num,
	       regexp_substr(part,'[^;]+',1,1) as key,
	       regexp_substr(part,'[^;]+',1,2) as value
      from split_data
)
	select dynasty,
	       json_arrayagg(
				josn_object(
					'key' VALUE key,
					'value' VALUE value,
					'order' value split_num
					)
			)
	   from key_value_pairs
	  group by dynasty

<三>、不足

  • 有的键值对比较大,在ORACLE是CLOB类型,不支持字符串拆分,只能用如下MYSQL方法,再进行数据同步

三、MYSQL

<一>、键值对拆分(RECURSIVE)

  • MYSQL中没有正则字符串拆分函数,只能用递归进行拆分
sql 复制代码
with recursive kv_split as (
	select dynasty,
	       trim(substring_index(value,';',1)) as kv_pairs,
	       trim(substring(value,char_length(substring_index(value,';',1)) + 2)) as remaining,
	       1 as splt_num
	  from table
	  union all
	select dynasty,
	       trim(substring_index(remaining,';',1)) as kv_pairs,
	       trim(substring(remaining,char_length(substring_index(value,';',1)) + 2)) as remaining,
	       split_num + 1 as splt_num
	  from kv_split
	 where remaining != ''
)
	select dynasty,kv_pairs,splt_num from kv_split

执行完为如下形式,跟ORACLE大同小异

dynasty part_num kv_pairs
唐朝 1 唐太宗:李世民
唐朝 2 唐高宗:李治
唐朝 3 唐玄宗:李隆基
汉朝 1 汉高祖:刘邦
汉朝 2 汉文帝:刘恒
汉朝 3 汉景帝:刘启
汉朝 4 汉武帝:刘彻
...

<二>、转为JSON

转成JSON跟ORACLE一样,有现成的转JSON函数,完整代码如下所示

sql 复制代码
with recursive kv_split as (
	select dynasty,
	       trim(substring_index(value,';',1)) as kv_pairs,
	       trim(substring(value,char_length(substring_index(value,';',1)) + 2)) as remaining,
	       1 as splt_num
	  from table
	  union all
	select dynasty,
	       trim(substring_index(remaining,';',1)) as kv_pairs,
	       trim(substring(remaining,char_length(substring_index(value,';',1)) + 2)) as remaining,
	       split_num + 1 as splt_num
	  from kv_split
	 where remaining != ''
)
	select dynasty,
	       json_arrayagg(
				json_object(
					'key',cast(substring_index(kv_pairs,':',1) as unsigned),
					'value',substring_index(kv_pairs,':',-1),
					'order',split_num
					)
			) as json_result
	  from kv_split
	 group by dynasty
相关推荐
Database_Cool_12 分钟前
云数据库如何保证高可用、故障了怎么办:阿里云 RDS MySQL 高可用架构详解
数据库·mysql·阿里云
中微极客32 分钟前
Veo视频生成与Gemini Agent平台集成实践
数据库·人工智能·oracle·音视频
江湖十年1 小时前
Go 语言中 YAML to JSON 踩坑笔记
后端·go·json
一棵星1 小时前
内网 MySQL 表结构一键导出 Word 文档:直连 + Agent 双模式实战
数据库·mysql·word
向日的葵0062 小时前
Redis会话机制vsJWT机制深度解析
数据库·redis·python·缓存·系统架构·jwt
bosins2 小时前
如何配置SQL Server数据库定时自动备份
数据库
烟雨归来2 小时前
RAC数据库OS进程消失,GV$SESSION长期残留KILLED僵尸会话处理
数据库·oracle
小龙报3 小时前
【优选算法】1. 水果成蓝 2.找到字符串中所有字母的异位词
java·c语言·数据结构·数据库·c++·redis·算法
宇宙第一小趴菜3 小时前
六、Oracle 目录结构
数据库·oracle
IvorySQL3 小时前
PG 日报|修复高 IO 并发场景,解决预读机制耗尽本地缓冲区缺陷
数据库·人工智能·sql·postgresql·区块链