如何编写 postgresql 查询来构建这样的 json 输出?

How to write postgresql query to build the json output like this?

我有一个 postgresql rational table,它有 2 级分层数据,我想编写一个查询来构建如下所示的 json 输出,我尝试了一些时间但无法弄清楚。我猜想需要使用一些功能,如 row_to_json、json_agg、json_build_object、json_build_array 等,但我真的无法成功完成。 任何人都可以提供帮助,谢谢!

将此有理数 table 作为输入:

select * from team;
+------------+------------+------------+
| country    | city       | member     |
|------------+------------+------------|
| china      | bejing     | betty      |
| china      | bejing     | bruce      |
| china      | shanghai   | scott      |
| usa        | chicago    | cindy      |
| usa        | newyork    | nancy      |
| usa        | newyork    | nathan     |
+------------+------------+------------+
SELECT 6

想要一个像下面这样的 json 作为输出:

[
    {
        "name": "china",
        "type": "country",
        "children": [
            {
                "name": "beijing",
                "type": "city",
                "children": [
                    { "name": "betty", "type": "member" },
                    { "name": "bruce", "type": "member" }
                ]
            },
            {
                "name": "shanghai",
                "type": "city",
                "children": [
                    { "name": "scott", "type": "member" }
                ]
            }
        ]
    },
    {
        "name": "usa",
        "type": "country",
        "children": [
            {
                "name": "chicago",
                "type": "city",
                "children": [
                    { "name": "cindy", "type": "member" }
                ]
            },
            {
                "name": "newyork",
                "type": "city",
                "children": [
                    { "name": "nancy", "type": "member" },
                    { "name": "nathan", "type": "member" }
                ]
            }
        ]
    }
]

以下是我对 table 结构的建议:

with team (country, city, member) as (
    values 
        ('china', 'bejing', 'betty'),
        ('china', 'bejing', 'bruce'),
        ('china', 'shanghai', 'scott'),
        ('usa', 'chicago', 'cindy'),
        ('usa', 'newyork', 'nancy'),
        ('usa', 'newyork', 'nathan')
) -- the real code is after this line
select jsonb_pretty(json_agg(json_build_object('name', c.country, 'type', 'country', 'children', ct.children) order by c.country)::jsonb)
from (select country from team group by country) c
left join (
    select ct.country, json_agg(json_build_object('name', ct.city, 'type', 'city', 'children', m.children) order by ct.city) as children
    from (select country, city from team group by country, city) ct
    left join (
        select country, city, json_agg(json_build_object('name', member, 'type', 'member') order by member) as children
        from team
        group by country, city
    ) m on ct.country = m.country and ct.city = m.city
    group by ct.country
) ct on c.country = ct.country;

我可能会写

SELECT json_agg(json_build_object(
   'type', 'country',
   'name', country,
   'children', children
)) AS root
FROM (
   SELECT country, json_agg(json_build_object(
       'type', 'city',
       'name', city,
       'children', children
   )) AS children
   FROM (
       SELECT country, city, json_agg(json_build_object(
           'type', 'member',
           'name', member
       )) as children
       FROM team
       GROUP BY country, city
   ) cities
   GROUP BY country
) countries

(online demo)

不幸的是,我没有找到在 json_build_object.

中使用子查询编写此代码的方法