Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

I have been searching around for an answer for this but haven't found anything close enough to what I was looking for.

I have two tables:

CREATE TABLE skill_tree (
    ID SERIAL PRIMARY KEY,
    NAME TEXT NOT NULL,
    DESCRIPTION TEXT NOT NULL
);

and

CREATE TABLE skill (
    ID SERIAL PRIMARY KEY,
    NAME TEXT NOT NULL,
    DESCRIPTION TEXT NOT NULL,
    DURATION INTEGER NOT NULL,
    COOLDOWN INTEGER NOT NULL,
    SKILL_TREE_ID SERIAL REFERENCES skill_tree(id)
);

I am trying to return JSON from my postgres db in such a way that it is structured like so:

[{
    "id": 1,
    "name": "skill tree 1",
    "description": "skill tree description",
    "skills": [{
        "id": 1,
        "name": "skill 1",
        "description": "skill 1 desc",
        "duration": 10,
        "cooldown": 20
    }, {
        "id": 2,
        "name": "skill 2",
        "description": "skill 2 desc",
        "duration": 20,
        "cooldown": 30
    }]
}]

I was able to get something similar from here [PostgreSQL and nodejs/pg, return nested JSON but wasn't able to retrieve anything more than the skill's name.

share|improve this question
1  
Now I see what is wrong. The SKILL_TREE_ID column can not be a serial. – Clodoaldo Neto Jul 19 at 12:47
up vote 5 down vote accepted

The table skill should look like this:

CREATE TABLE skill (
    ID SERIAL PRIMARY KEY,
    NAME TEXT NOT NULL,
    DESCRIPTION TEXT NOT NULL,
    DURATION INTEGER NOT NULL,
    COOLDOWN INTEGER NOT NULL,
    SKILL_TREE_ID INTEGER REFERENCES skill_tree(id) -- cannot be serial!
);

Use jsonb_build_object() and jsonb_agg(). Note, the query is somehow similar to the expected object.

select jsonb_pretty(jsonb_agg(js_object)) result
from (
    select 
        jsonb_build_object(
            'id', id, 
            'name', name, 
            'description', description, 
            'skills', jsonb_agg(skill)
        ) js_object
    from (
        select 
            t.*, 
            jsonb_build_object(
                'id', s.id, 
                'name', s.name, 
                'description', s.description, 
                'duration', duration, 
                'cooldown', cooldown
            ) skill
        from skill_tree t
        join skill s on s.skill_tree_id = t.id
        ) s
    group by id, name, description
    ) s;

I've wrapped the result with jsonb_pretty() to get a nice output:

                     result                      
-------------------------------------------------
 [                                              +
     {                                          +
         "id": 1,                               +
         "name": "skill tree 1",                +
         "skills": [                            +
             {                                  +
                 "id": 1,                       +
                 "name": "skill 1",             +
                 "cooldown": 20,                +
                 "duration": 10,                +
                 "description": "skill 1 desc"  +
             },                                 +
             {                                  +
                 "id": 2,                       +
                 "name": "skill 2",             +
                 "cooldown": 30,                +
                 "duration": 30,                +
                 "description": "skill 2 desc"  +
             }                                  +
         ],                                     +
         "description": "skill tree description"+
     }                                          +
 ]

Note that the order of elements of a json object is undefined.

share|improve this answer
    
looks like this is the fix! will try this tonight – rahsta9 Jul 19 at 13:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.