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

PostgreSQL使用jsonb_object_agg仅返回最后一行问题排查

问题原因
  • 合法的JSON对象不允许出现重复的键名,你期望的{"MyKey":{"Field1":"Value1"},"MyKey":{"Field2": "Value2"}}本身不符合JSON规范,无法被标准JSON解析器识别。
  • jsonb_object_agg聚合函数在遇到重复键时,会自动用后出现的键值覆盖前面的,所以你最终只得到了数组最后一个元素对应的键值对。
解决方法

你可以根据实际需求选择以下两种实现方案:

方案1:将同键的值合并为数组

最终输出结果为 {"MyKey": [{"Field1":"Value1"}, {"Field2":"Value2"}]},既保留了所有原始数据,也符合JSON规范,修改后的代码如下:

DO
$$
DECLARE
    varMyJson jsonb;
BEGIN

    varMyJson := '[{"Field1":"Value1"},{"Field2":"Value2"}]'::jsonb;
    RAISE NOTICE 'varMyJson : %', varMyJson;
    
    SELECT jsonb_build_object('MyKey', jsonb_agg(JsonString.value))
    INTO varMyJson
    FROM jsonb_array_elements(varMyJson) JsonString;
    RAISE NOTICE 'varMyJson : %', varMyJson;

END
$$

运行输出:

NOTICE:  varMyJson : [{"Field1": "Value1"}, {"Field2": "Value2"}]
NOTICE:  varMyJson : {"MyKey": [{"Field1": "Value1"}, {"Field2": "Value2"}]}

方案2:生成唯一键名

如果必须每个数组元素对应独立的顶级键,可以给键名加上序号保证唯一,最终输出类似{"MyKey1": {"Field1":"Value1"}, "MyKey2": {"Field2": "Value2"}},代码如下:

DO
$$
DECLARE
    varMyJson jsonb;
BEGIN

    varMyJson := '[{"Field1":"Value1"},{"Field2":"Value2"}]'::jsonb;
    RAISE NOTICE 'varMyJson : %', varMyJson;
    
    SELECT jsonb_object_agg(a.key, a.value)
    INTO varMyJson
    FROM
    (
        SELECT 'MyKey' || (row_number() over()) as key, JsonString.value
        FROM jsonb_array_elements(varMyJson) JsonString
    ) a;
    RAISE NOTICE 'varMyJson : %', varMyJson;

END
$$

运行输出:

NOTICE:  varMyJson : [{"Field1": "Value1"}, {"Field2": "Value2"}]
NOTICE:  varMyJson : {"MyKey1": {"Field1": "Value1"}, "MyKey2": {"Field2": "Value2"}}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:36:02