MySQL无JSON_TABLE时如何将JSON字典拆分为独立数据行
实现方案
无JSON_TABLE可用时,可通过手动构造数字序列的方式模拟JSON对象的行展开,核心原理是先用JSON_KEYS获取configs下所有键的数组,再按数组下标逐个取出键名和对应的配置值。
以下示例默认支持单条记录最多10个配置项,若需要支持更多配置项,扩展数字序列的数值范围即可:
SELECT -- 生成唯一ID,也可替换为CONCAT(tbl.id, '_', num.n) 性能更优 UUID() AS id, tbl.param1, tbl.param2, JSON_UNQUOTE(JSON_EXTRACT(tbl.config, '$.confToUse')) AS `use`, -- 取当前下标对应的配置名 JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(tbl.config, '$.configs'), CONCAT('$[', num.n, ']'))) AS `name`, -- 取对应配置名的配置内容 JSON_EXTRACT(tbl.config, CONCAT('$.configs.', JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(tbl.config, '$.configs'), CONCAT('$[', num.n, ']'))))) AS config, -- 生成use_id,即启用配置对应的行ID (SELECT UUID() FROM configs_table t2 WHERE t2.id = tbl.id AND JSON_UNQUOTE(JSON_EXTRACT(t2.config, '$.confToUse')) = JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(t2.config, '$.configs'), CONCAT('$[', num.n, ']'))) ) AS use_id FROM configs_table tbl -- 构造数字序列,需要支持更多配置项可补充更大的数值 JOIN ( SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) num WHERE tbl.id = 123 -- 过滤掉超出实际配置键数量的无效行 AND num.n < JSON_LENGTH(JSON_KEYS(tbl.config, '$.configs'));
注意说明
- 用到的
JSON_KEYS、JSON_LENGTH、JSON_UNQUOTE均为MySQL 5.7版本就支持的基础JSON处理函数,符合版本限制要求 JSON_UNQUOTE作用是去除JSON字符串自带的外层双引号,保证返回的配置名、启用配置字段为纯文本- 若不需要
use_id字段可直接删除对应SELECT子句,也可根据业务规则自行调整use_id的生成逻辑
内容的提问来源于stack exchange,提问作者Ivan Khorin
相关产品推荐
相关产品推荐

