MySQL отношения многие ко многим: справка с запросом - PullRequest
0 голосов
/ 26 октября 2010

Мой текущий код такой:

$select = $this->select()
               ->from(array('r' => 'recipes'), $this->getAdapter()
                                                    ->quoteInto("r.*, MATCH(title, directions) AGAINST(?) AS score", $searchText))
               ->where('MATCH(title, directions) AGAINST(?)', $searchText);

//SQL: SELECT r.*, MATCH(title, directions) AGAINST('chicken soup') AS `score` FROM `recipes` AS `r` WHERE (MATCH(title, directions) AGAINST('chicken soup')) 

Я хочу добавить дополнительное предложение WHERE для поиска только рецептов, которые содержат определенный ингредиент. Проблема, с которой я столкнулся, связана с тем, что таблица ингредиентов и моя таблица рецептов имеют много много связей, с соединительной таблицей attribute_recipes, в которой есть столбцы «id», «recipe_id» и «component_id».

Как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 26 октября 2010

Я не очень знаком с MySQL, но можно ли что-то подобное сделать?

SELECT r.* 
FROM recipes AS r 
LEFT JOIN recipe_sites AS s ON r.site_id = s.id 
WHERE '%salt%' IN (SELECT i.name
                   FROM ingredients AS i 
                   LEFT JOIN recipe_ingredients AS ri ON i.id = ri.ingredient_id 
                   LEFT JOIN recipes AS r ON ri.recipe_id = r.id) 
GROUP BY r.id;

Как правильно это сделать?

0 голосов
/ 26 октября 2010

Вот простой SQL для поиска рецептов по ингредиентам.Вы должны быть в состоянии экстраполировать специфику оттуда.

SELECT r.*
FROM recipes r
LEFT OUTER JOIN recipe_ingredients ri ON r.recipe_id = re.recipe_id
LEFT OUTER JOIN ingredients i on ri.ingredient_id = i.ingredient_id
WHERE i.ingredient_title = "[Your Ingredient Variable]"
GROUP BY r.recipe_id;

Для нескольких ингредиентов:

SELECT r.*
FROM recipes r
LEFT OUTER JOIN recipe_ingredients ri ON r.recipe_id = re.recipe_id
LEFT OUTER JOIN ingredients i on ri.ingredient_id = i.ingredient_id
WHERE i.ingredient_title = "[First Ingredient Var]"
OR i.ingredient_title = "[Second Ingredient Var]"
GROUP BY r.recipe_id;

Хотя, если вы пытаетесь найти что-то, что имеет оба (не один илидругой), вам может потребоваться выполнить два запроса (или, по крайней мере, дополнительный выбор), что может быть довольно медленным запросом в большой базе данных.

Лучшее, что я могу придумать для одного запроса, будетбыть примерно таким:

SELECT r.*
FROM recipes r
LEFT OUTER JOIN recipe_ingredients ri ON r.recipe_id = re.recipe_id
LEFT OUTER JOIN ingredients i1 on ri.ingredient_id = i1.ingredient_id
LEFT OUTER JOIN ingredients i2 on ri.ingredient_id = i2.ingredient_id
WHERE i1.ingredient_title = "[First Ingredient Var]"
AND i2.ingredient_title = "[Second Ingredient Var]"
GROUP BY r.recipe_id;

Где вы создаете еще одно объединение для каждого дополнительного ингредиента.Этот запрос не будет возвращать рецепты, в которых есть некоторые (но не все) ингредиенты, только рецепты, которые содержат ВСЕ ингредиенты, которые вы ищете.

...