You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GROUP BY查询中如何解决jsonb_object_keys报错并转为JSON字段名数组?

解决PostgreSQL GROUP BY中JSON键转数组的问题

这个报错我之前也碰到过,核心问题就是jsonb_object_keys是个返回多行结果的集合函数,直接放在GROUP BY的查询里,PostgreSQL没法把多行结果和分组后的单行对应起来,所以才会提示"set-valued function called in context that cannot accept a set"。

要解决这个问题,关键是把jsonb_object_keys返回的多行键值,通过聚合函数打包成单个数组。下面给你两种常用的实现方式:

方法1:用LATERAL JOIN + array_agg

这种方式先把每个JSON对象的键拆分成单独行,再按分组字段聚合数组,适合需要对键做额外过滤的场景:

SELECT 
    t.id, 
    -- 用COALESCE处理空JSON的情况,返回空数组而非NULL
    COALESCE(array_agg(DISTINCT j.key), '{}'::text[]) AS json_keys
FROM data_table t
-- LEFT JOIN LATERAL确保即使JSON为空也能保留分组行
LEFT JOIN LATERAL jsonb_object_keys(t.json_data) j(key) ON true
GROUP BY t.id;

方法2:用子查询聚合数组

如果逻辑比较简单,也可以直接在SELECT子句里用子查询把键聚合为数组,写法更紧凑:

SELECT 
    t.id,
    (SELECT array_agg(DISTINCT key) FROM jsonb_object_keys(t.json_data) key) AS json_keys
FROM data_table t
GROUP BY t.id;

注意事项

  • 加上DISTINCT是为了避免意外的重复键(虽然JSONB本身会自动去重重复键,但保险起见还是加上)
  • 用COALESCE可以把空JSON对应的NULL数组转换成空数组{},根据你的业务需求选择是否需要

举个实际例子,假设你的表数据是:

idjson_data
1{"name": "Alice", "age": 30}
2{"email": "bob@example.com"}
3{}

执行方法1的查询后,结果会是:

idjson_keys
1{"age", "name"}
2{"email"}
3{}

内容的提问来源于stack exchange,提问作者narrowtux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:43:10