MariaDB 10.2中带过滤的JSON数组元素求和及相关问题
问题解答
1. 提取的amount与flag数组元素顺序是否一致?
是一致的。JSON数组本身是有序集合,MariaDB的JSON_EXTRACT在使用[*]通配符提取数组元素时,会严格保留原JSON数组中的元素顺序。所以你提取的amounts数组和flag数组,对应位置的元素必然属于原details数组中的同一个对象,不会出现顺序错位的情况,求和时匹配对应位置是可靠的。
2. 无需代码处理的纯SQL求和方式
由于MariaDB 10.2不支持JSON_TABLE,可以用**递归CTE(公共表表达式)**来拆分JSON数组,实现纯SQL求和。具体SQL如下:
WITH RECURSIVE json_elements AS ( -- 初始行:获取每条记录的id、details数组,以及数组的长度 SELECT id, details, JSON_LENGTH(details) AS arr_length, 0 AS idx FROM your_table_name WHERE JSON_LENGTH(details) > 0 -- 过滤无details数据的行 UNION ALL -- 递归遍历数组的每个索引 SELECT id, details, arr_length, idx + 1 FROM json_elements WHERE idx + 1 < arr_length ) -- 提取每个元素的flag和amount,过滤flag为true的后求和 SELECT id, SUM( CASE WHEN JSON_EXTRACT(details, CONCAT('$[', idx, '].flag')) = 'true' THEN JSON_EXTRACT(details, CONCAT('$[', idx, '].amount')) ELSE 0 END ) AS total_amount FROM json_elements GROUP BY id;
说明:
- 递归CTE的
json_elements部分会生成每条记录对应details数组的所有索引(从0到数组长度-1)。 - 主查询中通过索引逐个提取每个元素的
flag和amount,判断flag为true时累加对应的amount,最后按id分组得到每个id的总和。 - 如果需要全局所有id的总和,去掉
GROUP BY id,直接用SUM(...)即可。
内容的提问来源于stack exchange,提问作者Gourav Roy
相关产品推荐
相关产品推荐

