简体   繁体   中英

Many-to-many combinations

I have the following standard many-to-many relation: http://sqlfiddle.com/#!9/43bd68/28/0

(simplified version) - I have product 1, which has categories 1, 2, 3 and product 2, which has categories 1, 3.

What I am trying to achieve is to select the products that belong to specific combination of categories.

To illustrate it:

  • Get products that belong to categories (1 or 2) and belong to categories (3). This should return both products 1 and 2
  • Get products that belong to categories (2) and belongs to categories (3). This should return only product 1

The categories should behave like "filters" - that's why my initial thought was to set WHERE category IN (1, 2) AND category IN (3) , but this does not work, as the category is a single value for one row. I think I need something like "foreach product and then inside the product check if it has category (1 or 2) and has category(3)".

Is it possible to achieve this with an SQL query?

You can use a query like the following:

SELECT
  p.name as prodName, p.id as pid
FROM
  Product p
JOIN Category_Product cp ON p.id = cp.product_id
JOIN Category c ON c.id = cp.category_id
WHERE category_id IN (2,3)
GROUP BY pid
HAVING COUNT(*) = 2

Demo here

To implement a query for the first case you have to use a conditional aggregate in HAVING clause:

SELECT
  p.name as prodName, p.id as pid
FROM
  Product p
JOIN Category_Product cp ON p.id = cp.product_id
JOIN Category c ON c.id = cp.category_id
WHERE category_id IN (1,2,3)
GROUP BY pid
HAVING COUNT(CASE WHEN category_id IN (1,2) THEN 1 END) > 0 AND
       COUNT(CASE WHEN category_id = 3 THEN 1 END) >= 1

Demo here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM