and3rsonsousa
02/21/2022, 6:05 PMErwin
02/21/2022, 7:10 PMErwin
02/21/2022, 7:11 PMjson
{
users: [ /* ... */ ],
posts: [ /* ... */ ],
other: [ /* ... */ ]
}
and3rsonsousa
02/22/2022, 3:11 AMErwin
02/22/2022, 9:53 AMSELECT to_jsonb(users.*) as users_json FROM users WHERE ...
- Gather all the results into a JSON array: SELECT coalesce(jsonb_agg(users_json), '[]') as users_array
- Nest levels of JSON hierarchy using lateral joins: they basically allow you to write for
loops in SQL, by allowing a subquery to have access to variables in statements that surround it. Highly recommend reading up on themErwin
02/22/2022, 9:55 AMcommon_id
and you want to retrieve all posts and users that reference that ID + let's say you want to nest all the comments for each post (to show how nesting works)Erwin
02/22/2022, 10:33 AMpgsql
create function get_users_and_posts(common_id uuid)
returns jsonb
language plpgsql
as $$
declare
users jsonb;
posts jsonb;
begin
-- Gather all JSON objects from `users` into an array
select coalesce(jsonb_agg(users.json), '[]')
into users
from (
-- Get each row of users into a JSON object
select to_jsonb(users.*) as json
from public.users
where users.common_id = common_id
) as users;
-- Gather all JSON objects from `posts` into an array
select coalesce(jsonb_agg(posts.json), '[]')
into posts
from (
-- merge post data and the nested `comments` array into a single JSON object
select to_jsonb(posts.*) || jsonb_build_object('comments', ljoin.comments) as json
from public.posts
-- gather comments
left join lateral (
select coalesce(jsonb_agg(comments.json), '[]') as comments
from (
select to_jsonb(comments.*) as json
from public.comments
-- the lateral join allows us to reference posts.id here!
where post_id = posts.id
) as comments
) as ljoin on true -- we just want to iterate over comments
) as posts;
return jsonb_build_object('users', users, 'posts', posts);
end;
$$
Erwin
02/22/2022, 10:33 AMErwin
02/22/2022, 10:33 AM