Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recipe Database, search by ingredient

I have the following 3 tables in my database, and am having some trouble querying them for the results I want. I'm trying to search for recipes by ingredients.

SQL Fiddle of the schema below: fiddle

Here are my tables: Ingredients

+---------------+---------+
| ingredient_id | name    |
+---------------+---------+
|             1 | tomato  |
|             2 | onion   |
|             3 | rice    |
|             4 | chicken |
|             5 | beef    |
|             6 | noodles |
|             7 | salt    |
+---------------+---------+

Recipes

+-----------+------------------+
| recipe_id | name             |
+-----------+------------------+
|         1 | tomato goodness  |
|         2 | meat deluxe      |
|         3 | chicken surprise |
+-----------+------------------+

Ingredient_Index

+-----------+---------------+
| recipe_id | ingredient_id |
+-----------+---------------+
|         1 |             1 |
|         1 |             5 |
|         1 |             7 |
|         2 |             5 |
|         2 |             6 |
|         2 |             7 |
|         3 |             4 |
|         3 |             3 |
|         3 |             7 |
+-----------+---------------+

a query to search for only one ingredient works fine, and outputs this:

mysql> select r.recipe_id, r.name
    -> from recipes r
    -> inner join ingredient_index
    -> on i.recipe_id = r.recipe_id
    -> where
    -> i.ingredient_id = 7;

+-----------+------------------+
| recipe_id | name             |
+-----------+------------------+
|         1 | tomato goodness  |
|         2 | meat deluxe      |
|         3 | chicken surprise |
+-----------+------------------+

But when using or for multiple ingredients we get this

mysql> select r.name
    -> from recipes r
    -> inner join ingredient_index i
    -> on i.recipe_id = r.recipe_id
    -> where i.ingredient_id = 7 or i.ingredient_id = 5;

+------------------+
| name             |
+------------------+
| tomato goodness  |
| tomato goodness  |
| meat deluxe      |
| meat deluxe      |
| chicken surprise |
+------------------+

5 rows in set (0.00 sec)

and using "and" results with nothing

    mysql>  select r.name
    ->  from recipes r
    ->  inner join ingredient_index i
    ->  on i.recipe_id = r.recipe_id
    ->  where i.ingredient_id = 7 and i.ingredient_id = 5;
Empty set (0.00 sec)

any help would be much appreciated!

like image 765
ThomasMalloch13 Avatar asked Nov 17 '12 03:11

ThomasMalloch13


1 Answers

Since a recipe can use multiple ingredients and you are looking for recipes that use one or more of the ingredients specified, you should use the DISTINCT keyword to prevent duplicate results where a recipe is using more than one ingredient from the list specified. Also, you can use IN clause to filter on multiple ingredient IDs.

select DISTINCT r.name
from 
    recipes r
    inner join ingredient_index i
    on i.recipe_id = r.recipe_id
where i.ingredient_id IN (7, 5);

Alternatively, if you are looking for recipes that are using all the ingredients specified in the list, then you can group the results by recipe name and check if the count of records is same as the number of ingredients in your list.

select r.name
from 
    recipes r
    inner join ingredient_index i
    on i.recipe_id = r.recipe_id
where i.ingredient_id IN (7, 5)
GROUP BY r.name
HAVING COUNT(*) = 2

This is assuming that there won't be duplicate records with same (recipe_id, ingredient_id) tuple (better ensured with a UNIQUE constraint).

like image 162
Vikdor Avatar answered Nov 08 '22 09:11

Vikdor