Reputation: 14866
I have this database:
create table if not exists blog
(
id serial primary key,
domain text
);
create table if not exists blog_category
(
id serial primary key,
name text
);
create table if not exists blog_to_blog_category
(
id serial primary key,
blog_id integer not null
constraint "FK_blog_to_blog_category_blog_BlogId"
references blog,
blog_category_id integer not null
constraint "FK_blog_to_blog_category_blog_category_BlogCategoryId"
references blog_category
);
INSERT INTO blog VALUES
(1, 'one.com'),
(2, 'two.com'),
(3, 'three.com');
INSERT INTO blog_category VALUES
(1, 'business'),
(2, 'marketing'),
(3, 'misc');
INSERT INTO blog_to_blog_category VALUES
(1, 1, 1),
(2, 1, 2),
(3, 1, 3),
(4, 2, 1),
(5, 2, 3);
I can get the data in format that I want by making a query like this:
select b.id, b.domain, coalesce( array_agg(bc.name)
filter (where bc.id is not null), '{}' ) as cats
from blog b
left join blog_to_blog_category bt on bt.blog_id = b.id
left join blog_category bc on bc.id = bt.blog_category_id
group by b.id
However, I can't work out how to filter it and also keep each record showing all categories it is in. for example:
select b.id, b.domain, coalesce( array_agg(bc.name)
filter (where bc.id is not null), '{}' ) as cats
from blog b
left join blog_to_blog_category bt on bt.blog_id = b.id
left join blog_category bc on bc.id = bt.blog_category_id
where bc.name = 'marketing'
group by b.id
It filters the blog correctly but now I can't aggregate all categories into a field. It only shows 1 category the blog is in.
What is the simplest way to be able to filter blogs and get a list of all of their categories?
Upvotes: 1
Views: 26
Reputation: 848
Try to select blog_id
from blog_to_blog_category
by blog_category.name
select b.id, b.domain, coalesce( array_agg(bc.name)
filter (where bc.id is not null), '{}' ) as cats
from blog b
left join blog_to_blog_category bt on bt.blog_id = b.id
left join blog_category bc on bc.id = bt.blog_category_id
where bt.blog_id = (
select bt.blog_id from blog_to_blog_category bt
left join blog_category bc on bc.id = bt.blog_category_id
where bc.name = 'marketing'
)
group by b.id;
Upvotes: 1