Reputation: 10422
I have a table that maps products to categories. Each product can belong to multiple categories, so a product can have multiple rows with different category IDs. It looks something like this:
CREATE TABLE `products_mid` (
`id` int(11) UNSIGNED NOT NULL,
`product_id` int(11) UNSIGNED NOT NULL DEFAULT '0',
`category_id` int(11) UNSIGNED NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
If I want to get a list of all product IDs that are in category A
that's simple enough-- but is there a way to get all product_id
s where they belong to categories A
, B
and C
as simply as possible?
Upvotes: 1
Views: 60
Reputation: 521093
Another way:
SELECT product_id
FROM products_mid
WHERE category_id IN (1, 2, 3)
GROUP BY product_id
HAVING COUNT(DISTINCT category_id) = 3
This would find all products in categories 1 through 3, although a product could also belong to other categories. If you want products which exclusively belong to category 1 through 3, and no others, then we would have to rephrase the query.
Upvotes: 1
Reputation: 28499
Use the intersect
operator to find the common values of three separate queries.
select product_id from products_mid where category_id = 1
intersect
select product_id from products_mid where category_id = 2
intersect
select product_id from products_mid where category_id = 3
Upvotes: 1
Reputation: 5697
It will be something like this:
select product_id from products_mid
where
category_id in (1,2,3)
group by product_id
having count(distinct category_id)=3
Upvotes: 2
Reputation: 726539
A better approach is to do it with HAVING
clause, not a WHERE
clause. Group by product_id
, and select rows having non-zero count of each of your three categories, like this:
SELECT product_id
GROUP BY product_id
HAVING SUM(CASE WHEN category_id=1 THEN 1 ELSE 0 END) > 0
AND SUM(CASE WHEN category_id=2 THEN 1 ELSE 0 END) > 0
AND SUM(CASE WHEN category_id=3 THEN 1 ELSE 0 END) > 0
The above statement selects product_id
s of products that belong to all three categories with IDs 1, 2, and 3.
Upvotes: 3