0

I want to create filter query which uses AND and OR on many to many relation table.

Table consists only of 2 columns id_product and id_category

My query I'm using, but its not working:

SELECT id_product FROM id_category WHERE ( id_category = 1)  AND (id_category = 2) 
AND ( id_category = 3 OR id_category = 4 OR id_category = 5) GROUP BY id_product

I would like to retrieve products that are in categories at the same time. Only IDs of products which are in category 1 AND 2 AND (3 or 4 or 5)

3
  • we need to see the rest of the query because you will likely have to either do multiple joins to the same table or a subquery Commented May 20, 2019 at 11:49
  • 2
    id_category cannot be at the same time 1 and 2.. So seems natural that a WHERE ( id_category = 1) AND ( id_category = 2) [..etc] will always return an empty result Commented May 20, 2019 at 11:50
  • Its a many to many relation as noted in question :) So id_product is not unique. Commented May 20, 2019 at 12:53

2 Answers 2

3

You must group by id_product and put these conditions in a HAVING clause:

SELECT id_product 
FROM tablename
GROUP BY id_product 
HAVING 
  SUM(id_category = 1) > 0
  AND
  SUM(id_category = 2) > 0
  AND
  SUM(id_category IN (3, 4, 5)) > 0
Sign up to request clarification or add additional context in comments.

Comments

2

Just for fun, to use a single condition in the HAVING clause:

SELECT id_product
FROM yourTable
WHERE id_category BETWEEN 1 AND 5
GROUP BY id_product
HAVING
    COUNT(DISTINCT CASE WHEN id_category IN (3, 4, 5)
                        THEN 3 ELSE id_category END) = 3;

Demo

The logic here is to first restrict the query to only id_category values (1,2,3,4,5). Then, we assert but first map id_category values of (3,4,5) to the same single value 3. The assertion is that the distinct count of mapped id_category values is 3, which would imply that 1, 2, and (3,4,5) all occur for that product.

2 Comments

Thank you for answer. great to know, but other one is easier to dynamically build and "seems" faster.
@Grzegorz Yes, I would probably use the other version in a production code base as well. I only gave this answer just to show that we can write a more terse query with a little SQL magic ^ ^.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.