PostgreSQL:如何从 GROUP BY ROLLUP 数据生成 JSON
PostgreSQL: How to Generate JSON from GROUP BY ROLLUP data
我需要一些帮助来将 Group By ROLLUP(...) 聚合到嵌套的 JSON.
我的查询(结果)如下图
查询#1
SELECT main, sub, subsub, count(*) FROM test
GROUP BY ROLLUP(main, sub, subsub)
ORDER BY main, sub, subsub;
结果
| main | sub | subsub | count |
| ---- | --- | ------ | ----- |
| c | c-1 | c-1-1 | 1 |
| c | c-1 | c-1-2 | 1 |
| c | c-1 | | 2 |
| c | | | 2 |
| d | d-1 | d-1-1 | 1 |
| d | d-1 | | 1 |
| d | | | 1 |
| | | | 3 |
但我希望它的结果在 json 中,如下所示
{
c: {
'total': 2,
c-1: {
'total': 2,
'c-1-1': 1,
'c-1-2': 1,
}
},
d: {
'total': 1,
'd-1': {
'total': 1,
'd-1-1': 1
}
}
}
我已经尝试了 json_build_object 之类的方法,但我无法操作 ROLLUP 数据。非常感谢任何帮助!
这里是 link to the fiddle (PostgreSQL V10)
您需要分层查询:
with totals as (
select main, sub, subsub, count(*)
from test
group by rollup(main, sub, subsub)
order by main, sub, subsub
)
select jsonb_object_agg(main, sub) as main
from (
select
main,
jsonb_object_agg(
coalesce(sub, 'total'),
case when sub is null
then subsub->'total'
else subsub end
) as sub
from (
select
main, sub,
jsonb_object_agg(
coalesce(subsub, 'total'), count
) as subsub
from totals
group by main, sub
having main is not null
) s
group by main
) m
where main is not null
没有cte的版本:
select jsonb_object_agg(main, sub) as main
from (
select
main,
jsonb_object_agg(
coalesce(sub, 'total'),
case when sub is null
then subsub->'total'
else subsub end
) as sub
from (
select
main, sub,
jsonb_object_agg(
coalesce(subsub, 'total'),
count
) as subsub
from (
select main, sub, subsub, count(*)
from test
group by rollup(main, sub, subsub)
) subsub
group by main, sub
having main is not null
) sub
group by main
) main
where main is not null
我需要一些帮助来将 Group By ROLLUP(...) 聚合到嵌套的 JSON.
我的查询(结果)如下图
查询#1
SELECT main, sub, subsub, count(*) FROM test
GROUP BY ROLLUP(main, sub, subsub)
ORDER BY main, sub, subsub;
结果
| main | sub | subsub | count |
| ---- | --- | ------ | ----- |
| c | c-1 | c-1-1 | 1 |
| c | c-1 | c-1-2 | 1 |
| c | c-1 | | 2 |
| c | | | 2 |
| d | d-1 | d-1-1 | 1 |
| d | d-1 | | 1 |
| d | | | 1 |
| | | | 3 |
但我希望它的结果在 json 中,如下所示
{
c: {
'total': 2,
c-1: {
'total': 2,
'c-1-1': 1,
'c-1-2': 1,
}
},
d: {
'total': 1,
'd-1': {
'total': 1,
'd-1-1': 1
}
}
}
我已经尝试了 json_build_object 之类的方法,但我无法操作 ROLLUP 数据。非常感谢任何帮助!
这里是 link to the fiddle (PostgreSQL V10)
您需要分层查询:
with totals as (
select main, sub, subsub, count(*)
from test
group by rollup(main, sub, subsub)
order by main, sub, subsub
)
select jsonb_object_agg(main, sub) as main
from (
select
main,
jsonb_object_agg(
coalesce(sub, 'total'),
case when sub is null
then subsub->'total'
else subsub end
) as sub
from (
select
main, sub,
jsonb_object_agg(
coalesce(subsub, 'total'), count
) as subsub
from totals
group by main, sub
having main is not null
) s
group by main
) m
where main is not null
没有cte的版本:
select jsonb_object_agg(main, sub) as main
from (
select
main,
jsonb_object_agg(
coalesce(sub, 'total'),
case when sub is null
then subsub->'total'
else subsub end
) as sub
from (
select
main, sub,
jsonb_object_agg(
coalesce(subsub, 'total'),
count
) as subsub
from (
select main, sub, subsub, count(*)
from test
group by rollup(main, sub, subsub)
) subsub
group by main, sub
having main is not null
) sub
group by main
) main
where main is not null