I have 3 main table : products, stores and categories
product relate many-to-many with stores via table product_store
product relate many-to-many with categories via table product_category
How can i query all products, belongs a store ( with store_id : 1 ) and belongs one or many category ( with category_id in [ 4,5,6 ] ? I used below syntax, but result has duplicated product records (for example, product in both category 5 and 6, will show 2 times). Can I get it unique ?
select
"products"."name"
from
"products"
inner join "product_categories" as "categories_join" on "categories_join"."product_id" = "products"."id"
inner join "categories" on "categories_join"."category_id" = "categories"."id"
inner join "product_stores" as "stores_join" on "stores_join"."product_id" = "products"."id"
inner join "stores" on "stores_join"."store_id" = "stores"."id"
where
"categories"."id" in ( 4,5,6,7 )
and "stores"."id" = 1
Advertisement
Answer
You can use select distinct
to return only one product. However, you can also simplify your query by removing a join
. The stores
and categories
tables are not needed, because you are only using the ids and these are available in the junction tables. I would also use simpler table aliases:
select distinct p."name"
from "products" p join
"product_categories" pc
on pc."product_id" = p."id" join
"product_stores" ps
on ps."product_id" = p."id"
where pc.category_id in ( 4,5,6,7 ) and
ps."id" = 1;
Note: You should avoid using double quotes for identifiers. If your tables are defined using them, then I would suggest fixing the table definitions.
This query, in turn, would probably be more efficient using exists
because select distinct
would no longer be necessary:
select p."name"
from "products" p
where exists (select 1
from "product_categories" pc
where pc."product_id" = p."id" andf
pc.category_id in ( 4,5,6,7 )
) and
exists (select 1
from "product_stores" ps
where ps."product_id" = p."id" and
ps."id" = 1
);