2

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 WINDOWs?

1 Answer 1

3
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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.