views:

30

answers:

2

I'm trying to do something like the PHP array_intersect. I have the following table

CREATE TABLE `recipes_ingredients_items` (
  `id` INTEGER(11) DEFAULT NULL,
  `itemid` INTEGER(11) DEFAULT NULL,
  `orderby` TINYINT(4) NOT NULL,
  KEY `id` (`id`),
  KEY `itemid` (`itemid`)
)ENGINE=MyISAM
AVG_ROW_LENGTH=47 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';  

I need a query that will get me all the results that contain say id 2,72,64 as a distinct itemid. The thing is that an id may exist more than once in an itemid, i.e itemid 600 may have 3 rows with ids 2,100,2 asociated with it.
My idea was to have a query with say x number o subqueries returning results and doing something like the PHP array_intersect, thus returning the itemids that have all these ids.

SELECT DISTINCT itemid  FROM recipes_ingredients_items
WHERE 
id IN (SELECT DISTINCT itemid FROM recipes_ingredients_items WHERE id = 71) 
AND 
id IN (SELECT DISTINCT  itemid FROM recipes_ingredients_items WHERE id = 2)
AND 
id IN (SELECT DISTINCT  itemid FROM recipes_ingredients_items WHERE id = 22)

This is what I got and it is 100% wrong.

+3  A: 

Try this:

SELECT item_id
FROM recipes_ingredients_items
WHERE id IN (71, 2, 22)
GROUP BY item_id
HAVING COUNT(*) = 3
Mark Byers
+1 Way better than mine.
Gumbo
But what if there are more than just one *itemid* per *id*?
Gumbo
+1  A: 

Normally you would do an intersection of the itemid‍s of each id:

(SELECT DISTINCT itemid FROM recipes_ingredients_items WHERE id = 71)
INTERSECT
(SELECT DISTINCT itemid FROM recipes_ingredients_items WHERE id = 2)
INTERSECT
(SELECT DISTINCT itemid FROM recipes_ingredients_items WHERE id = 22)

This will only select those itemid‍s where there is an id for all three id‍s.

But since MySQL does not support INTERSECT, you need to use inner joins:

SELECT DISTINCT itemid FROM recipes_ingredients_items
INNER JOIN (SELECT DISTINCT itemid FROM recipes_ingredients_items WHERE id = 71) a USING (itemid)
INNER JOIN (SELECT DISTINCT itemid FROM recipes_ingredients_items WHERE id = 2) b USING (itemid)
INNER JOIN (SELECT DISTINCT itemid FROM recipes_ingredients_items WHERE id = 22) c USING (itemid)
Gumbo
thanks a lot, that's what i was looking for!
mbouclas
+1 this also works if there are duplicates.
Mark Byers