PostgreSQL中筛选JSON对象多随机子键满足条件的行
筛选JSON列中存在非true的success字段的行
针对你描述的JSON结构(公共键a下有数量、名称均未知的子键,每个子键包含success字段),要筛选出**至少有一个子键的success不为true**的行(比如示例中的第一行),可以用PostgreSQL的JSON函数实现,以下是两种可行方案:
方案1:用json_each结合EXISTS子查询
通过展开a下的所有子对象,检查是否存在符合条件的条目:
SELECT * FROM my_table WHERE EXISTS ( SELECT 1 FROM json_each(json_col::json -> 'a') AS j(key, value) WHERE (j.value ->> 'success')::boolean IS NOT TRUE );
细节说明:
json_each(json_col::json -> 'a'):将a下的所有键值对拆分为多行记录,key是子键名称(如x、y、z),value是对应的子对象。(j.value ->> 'success')::boolean IS NOT TRUE:该条件会匹配两种情况:success字段值为false,或者success字段不存在(转换后为NULL)。如果只需要筛选success明确为false的行,把条件改成(j.value ->> 'success')::boolean = FALSE即可。
方案2:用jsonb_path_exists(推荐用于大数据量场景)
如果你的列是jsonb类型(或可转换为jsonb),可以用JSON路径查询实现更简洁的写法:
SELECT * FROM my_table WHERE jsonb_path_exists( json_col::jsonb, '$.a.* ? (@.success != true)' );
细节说明:
$.a.*:匹配a下的所有子对象。? (@.success != true):筛选出success不等于true的子对象,只要存在这样的对象,该行就会被选中。
补充说明
你原来的SQL无法直接实现需求,因为a下的子键名称不固定,无法通过固定键名定位,必须先将所有子键展开后逐个检查success字段的值,这也是上述方案的核心逻辑。
内容的提问来源于stack exchange,提问作者maxwell_rob33
相关产品推荐
相关产品推荐

