简体   繁体   中英

Postgres: Nested Aggregate JSON

The table I'm querying looks like this:

namespace | key   | value
---------------------------
foo       | bar   | baz
foo       | alpha | beta
gamma     | delta | epsilon

And I'd like to pull it out of the database like this:

{
    "foo": {
        "bar": "baz",
        "alpha": "beta"
    },
    "gamma": {
        "delta": "epsilon"
    }
}

Playing around with json_object_agg isn't really getting me past the first level, since you're not allowed to nest aggregate functions. But as far as I can see, I need a GROUP BY within a GROUP BY , but I'm not sure if that's possible. Perhaps the solution has to do with WINDOW s?

with t (namespace, key, value) as (
    values
    ('foo','bar','baz'),('foo','alpha','beta'),('gamma','delta','epsilon')
), s as (
    select namespace, json_object_agg(key, value) as joa
    from t
    group by namespace
)
select json_object_agg(namespace, joa)
from s
;
                                  json_object_agg                                   
------------------------------------------------------------------------------------
 { "foo" : { "bar" : "baz", "alpha" : "beta" }, "gamma" : { "delta" : "epsilon" } }

As a CTE is an optimization barrier this version might be faster:

with t (namespace, key, value) as (
    values
    ('foo','bar','baz'),('foo','alpha','beta'),('gamma','delta','epsilon')
)
select json_object_agg(namespace, joa)
from (
    select namespace, json_object_agg(key, value) as joa
    from t
    group by namespace
) s

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM