'Nesting json_agg() inside json_agg()
I have these 2 tables tasks and subtasks with these columns:
Tasks
id
name
description
Subtasks
id
name
description
task_id
I'm trying to do a query that would output something like this:
[
{
id:30,
name:"Do something",
description:"Do this",
sub_task:[
{id:1,name:"test",description:"test"}
]
}
]
After some research I found out how to query data as json and it works if I don't have something nested, and I can't figure out how to do it. This is what I tried:
let query =
"SELECT t.id, json_agg(json_build_object('name',t.name,'description',t.description,'id',t.id,'subtask',json_agg(json_builder_object('name',s.name,'description',s.description)))) as test from task t ";
query += " inner join subtask s on s.task_id = t.id ";
I tried to do this nested json_agg()
but I get this error:
json_builder_object(unknown, character varying, unknown, text) does not exist
How should I do it?
Solution 1:[1]
Well, it's json_build_object()
, not .json_builder_object()
But the main issue is that you cannot nest aggregate functions. You need a subquery or a CTE for that. Like:
SELECT json_agg(json_build_object('id',t.id, 'name',t.name, 'description',t.description, 'subtask',s.sub_task)) AS task
FROM tasks t
CROSS JOIN LATERAL (
SELECT json_agg(json_build_object('id',s.id, 'name',s.name, 'description',s.description)) AS sub_task
FROM subtasks s
WHERE task_id = t.id
) s;
Or equivalent:
SELECT json_agg(t) AS tasks
FROM (
SELECT *
FROM tasks t
CROSS JOIN LATERAL (
SELECT json_agg(sub_task) AS sub_task
FROM (
SELECT id, name, description
FROM subtasks
WHERE task_id = t.id
) sub_task
) s
) t;
Related:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |