如何将数组(或jsonb_array)转换为嵌套的json对象?

问题描述 投票:0回答:1

我有一组数据,比如说一组 json 对象。像这样:

[
  { "id": 1, "name": "level 1"},
  { "id": 3, "name": "level 2"},
  { "id": 8, "name": "level 3"}
]

我想根据它们在数组中的顺序嵌套这些项目

{ 
  "id": 1,
  "name": "level 1",
  "child": { 
    "id": 3,
    "name": "level 2",
    "child": { 
      "id": 8,
      "name": "level 3"
    } 
  }
}

到目前为止,我能想到的唯一方法是构建自定义聚合,但这不仅需要大量工作,而且在部署方面也很困难(这不是我的数据库)

有没有办法在查询中做到这一点?

到目前为止,我正在考虑使用 unnest 为数组中的每个项目创建不同的行。然后向行添加行号以维持顺序,然后以某种方式将第 2 行中的项目添加到第 1 行的项目中..但到目前为止我还无法做到这一点..而且它必须是递归的,我不这样做不知道能不能成功

换句话说..我需要帮助..

json postgresql aggregate
1个回答
0
投票

使用自定义聚合的解决方案

CREATE FUNCTION nested_jsonb (a jsonb, b jsonb) RETURNS jsonb LANGUAGE sql IMMUTABLE AS 
$$   
SELECT CASE
         WHEN a IS null THEN b
         ELSE b || jsonb_build_object('child', a)
       END ;
$$ ;

CREATE AGGREGATE nested_jsonb(c jsonb)
( sfunc = nested_jsonb 
, stype = jsonb 
) ;

然后使用 json 对象数组运行以下查询:

SELECT nested_jsonb (a.content ORDER BY a.id DESC)
  FROM jsonb_array_elements
            ('[ { "id": 1, "name": "level 1"}
              , { "id": 3, "name": "level 2"}
              , { "id": 8, "name": "level 3"}
              ]' :: jsonb
            ) WITH ORDINALITY AS a(content,id)

你就得到了预期的结果

{"id": 1, "name": "level 1", "child": {"id": 3, "name": "level 2", "child": {"id": 8, "name": "level 3"}}}

参见dbfiddle

© www.soinside.com 2019 - 2024. All rights reserved.