如何编写 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
不幸的是,我没有找到在 json_build_object
.
中使用子查询编写此代码的方法
我有一个 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
不幸的是,我没有找到在 json_build_object
.