MariaDB中如何检测JSON任意子属性是否包含true值
在MariaDB中检查JSON任意子属性是否包含true值
问题描述
我有如下JSON:
{"a": {"z":true,"y":false}, "b": {"z":false,"y":false} }
需要在MariaDB中判断该JSON的任意(子)属性是否包含值true。
尝试了以下SQL查询:
SET @json='{"a": {"z":true,"y":false}, "b": {"z":false,"y":false} }'; SELECT JSON_CONTAINS(@json,'true'),JSON_CONTAINS(@json,'true','$.a'),JSON_CONTAINS(@json,'true','$.a.z');
但前两个查询返回0,仅最后一个返回1。虽然可以逐个检查每个子属性再通过CASE判断,但希望有更简便的实现方式。
原因分析
JSON_CONTAINS的匹配逻辑是完整匹配目标路径的结构:
- 直接用
JSON_CONTAINS(@json,'true')会检查整个JSON是否等于字符串'true',显然不成立 JSON_CONTAINS(@json,'true','$.a')会检查$.a对应的对象是否等于字符串'true',同样不成立- 只有
$.a.z是布尔值true,和传入的'true'(MariaDB会自动转换类型)匹配,所以返回1
简便实现方案
使用JSON_TABLE递归遍历JSON所有层级的叶子节点,再通过EXISTS判断是否存在true值,无需手动指定每个子属性路径:
SET @json='{"a": {"z":true,"y":false}, "b": {"z":false,"y":false} }'; SELECT EXISTS( SELECT 1 FROM JSON_TABLE( JSON_QUERY(@json, '$'), '$.**[*]' COLUMNS ( leaf_value BOOLEAN PATH '$' ) ) AS json_leaves WHERE leaf_value = true ) AS has_true_value;
$.**[*]是递归通配符,会匹配JSON中所有层级的叶子节点JSON_TABLE将这些叶子节点转换为表格形式,提取布尔值EXISTS会在找到任意一个true时立即返回1,否则返回0
这个方法适用于任意深度的JSON结构,无需修改SQL适配结构变化。
内容的提问来源于stack exchange,提问作者John Schols
相关产品推荐
相关产品推荐

