Reputation: 6291
My schema is composed like this:
channel
-> channels_categories
-> category
A channel can have many categories, and categories can belong to many channels.
When i query for channels, i would like to get the channels categories with them.
Anyway if i use JOIN
i will simply get the channel duplicated for each category.
[
{
"channel_name": "Channel1",
"category_name": "Category1",
"category_id": "1"
},
{
"channel_name": "Channel1",
"category_name": "Category2"
"category_id": "2"
}
]
The ideal result format (JSON) would be something like:
{
channel_name: 'Channel1',
categories: [{/**category**/}, ....]
}
Is there a way i can achieve this result format just with SQL?
Upvotes: 0
Views: 114
Reputation: 332
I just noticed that you really want the result in the JSON format, this answer is about combining and merging attributes into JSON lists.
You can use string_agg and concat to combine the category_name and category_id to lists like this:
select channel_name,
concat('[', string_agg(category_name, ','), ']') as category_names,
concat('[', string_agg(cast(category.id as text), ','), ']') as category_ids
from
channel inner join channel_category on channel.id = channel_category.channel_id
inner join category on channel_category.category_id = category.id
group by channel_name;
Which produces results like that:
| channel_name | category_names | category_ids |
| channel1 | [category1,category2]| [1,2] |
For a complete JSON result melpomene's answer seems to fit your needs way better than this.
Upvotes: 0
Reputation: 85767
This is completely untested but I've looked at the manual for JSON functions and it looks like the following might work:
select jsonb_build_object(
'channel_name', channel.name,
'categories', jsonb_agg(
jsonb_build_object(
'category_id', category.id,
'category_name', category.name
)
)
)
from channel
join channels_categories on channel.id = channel_id
join category on category.id = category_id
group by channel.id
This assumes that channel
has a primary key called id
.
Upvotes: 3