MariaDB 10.3无JSON_TABLE时如何动态生成序列解析JSON时间区间数组
解决方案
针对MariaDB 10.3版本不支持JSON_TABLE的场景,推荐用递归CTE生成动态索引序列的方案实现需求,完全不需要硬编码索引值:
方案说明
你之前的写法核心问题是索引序列硬编码,我们可以用递归CTE自动生成覆盖所有数组长度的连续索引,再通过表中已有的howmany字段过滤有效索引即可。
另外你之前用REPLACE去除JSON返回值的引号可以替换为原生的JSON_UNQUOTE函数,写法更简洁不易出错。
可直接运行的查询代码
-- 如果你的JSON数组最长超过1000个元素,可以先临时调大递归深度(按需调整数值) -- SET SESSION cte_max_recursion_depth = 10000; WITH RECURSIVE indexes AS ( -- 起始索引从0开始,符合JSON数组下标规则 SELECT 0 AS idx UNION ALL -- 递归自增,直到覆盖表中最大的数组长度 SELECT idx + 1 FROM indexes WHERE idx < (SELECT MAX(howmany) - 1 FROM test.json) ) SELECT idx, JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$[', idx, '].from'))) AS `from`, JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$[', idx, '].to'))) AS `to` FROM test.json -- 只取每个JSON数组实际存在的元素索引,避免生成无效行 JOIN indexes ON indexes.idx < test.json.howmany -- 可选:过滤非法JSON避免报错 WHERE JSON_VALID(json);
备选方案(不支持CTE的极端场景)
如果你的环境因故无法使用递归CTE,可以提前创建一个固定长度的数字辅助表,存储从0到你业务场景中最大可能的JSON数组长度的连续数字,关联逻辑和上面一致:
-- 先创建数字辅助表,只需要创建一次 CREATE TABLE IF NOT EXISTS num_seq (num INT PRIMARY KEY); -- 插入足够多的数字,比如0~1000,覆盖你业务最大数组长度即可 INSERT INTO num_seq (num) VALUES (0),(1),(2),...,(1000); -- 查询时关联辅助表 SELECT num AS idx, JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$[', num, '].from'))) AS `from`, JSON_UNQUOTE(JSON_EXTRACT(json, CONCAT('$[', num, '].to'))) AS `to` FROM test.json JOIN num_seq ON num_seq.num < test.json.howmany WHERE JSON_VALID(json);
内容的提问来源于stack exchange,提问作者Răzvan T.
相关产品推荐
相关产品推荐

