2015-01-01 2 views
0

У меня есть таблица со следующей схемой в MySQLпоиск для всех комбинаций значений в столбце из определенного подмножества

Recipe_Quantity_ID, Recipe_ID, Recipe_Quantity, Ingredients_ID, Ingredient_Measurement_ID

Данные образцы могут быть найдены в это SQL Fiddle http://sqlfiddle.com/#!2/d05fe.

Я хочу найти таблицу для данных (одного или многих) Ingredients_ и вернуть Recipe_ID, который имеет этот Ingredients_ID

Я делаю это с помощью этого SQL

select Recipe_ID 
from recipe_quantity 
group by Recipe_ID 
having count(*) = {$ar_rows} 
and sum(Ingredients_ID in ({$ids})) = {$ar_rows} 

, который может перевести на

select Recipe_ID 
from recipe_quantity 
group by Recipe_ID 
having count(*) = 4 
and sum(Ingredients_ID in (8,5,45,88)) = 4 

Для поиска меньше Ingredients_ID Я вычитаю последний идентификатор, пока не достигню одного Ингредиента. С помощью этой методики, конечно, невозможно найти все комбинации. Например, 8,5,45,85 | 8,45,85 | 45,85 | 5,45,85 и т. Д.

Любые идеи, как я могу искать все комбинации, которые могут быть правдой? Заранее спасибо.

ответ

0

Я понимаю, что вы хотите получить все рецепты, в которых у вас уже есть все необходимые ингредиенты. вам не нужно использовать все ингредиенты, которые у вас есть, но вы не хотите ходить по магазинам.

Исправьте меня, если я ошибаюсь, но я не думаю, что есть рецепт, который соответствует вашему списку ингредиентов, поэтому я использовал другие ингредиенты. обратите внимание, что ингредиенты 13,36 не будут использоваться.

Вы должны быть в состоянии поставить другой оператор выбора в скобках, которые получают ингредиенты, которые у вас есть (выберите components_id from components_owned), это нехорошо указывать их каждый раз.

select distinct c.Recipe_id 
from 
    (select Recipe_ID 
    from recipe_quantity 
    where Ingredients_ID in (5,6,1,11,8,12,13,36, 81,82,62,73,35)) c 
    left join (select Recipe_ID 
       from recipe_quantity 
       where Ingredients_ID not in (5,6,1,11,8,12,13,36, 81,82,62,73,35)) x 
    on c.Recipe_id = x.Recipe_id 
where x.Recipe_id is null 
+0

Да, вы понимаете правильно, код работает отлично, но я не могу полностью понять ваш код. Я потерял тебя слева. Хотя я получил ответ, который искал, я хотел бы понять код. Если у вас есть время, оставьте комментарий, объясняющий это решение. Большое спасибо и с Новым годом. – Kiki

+1

Если вы хотите лучше понять соединения, это хороший пост http://stackoverflow.com/questions/38549/difference-between-inner-and-outer-joins/16598900#16598900. В частности, я использую левое соединение и проверяю значение null, чтобы исключить любой рецепт, который содержит ингредиенты, которых у вас нет. "not in (list)" надеюсь, что это поможет ... Happy NY 2u2 :-) –

+0

Большое спасибо за ответ и сослался на него, чтобы понять его. – Kiki

0

Как насчет чего-то подобного?

select Recipe_ID, group_concat(Ingredients_ID), count(*) as ingredients 
from recipe_quantity 
where Ingredients_ID IN (8,5,45,88) 
group by Recipe_ID 
having ingredients > 0 
order by ingredients desc 

Вместо того, чтобы сгруппировать все компоненты рецепта, а затем отфильтровать те, которые не включают в себя ингредиенты, которые вы ищете, я сопрягать только записи в recipe_quantity, которые соответствуют ингредиенты в первую очередь. Я использую group_concat, чтобы вы могли видеть набор ингредиентов, которые соответствуют.

Это заказывает количество ингредиентов, которые соответствуют, но при этом сохраняют частичные спички на одном или нескольких ингредиентах. Вы меняете 0 на минимальное количество ингредиентов.

+0

Нет, это вернет recipe_id (s), который содержит и другие ингридиенты. Я хочу вернуть recipe_id (s) из ингредиентов, которые были предоставлены. Спасибо, что позаботился об этом. Например. У пользователя может быть 30 ингредиентов в холодильнике, я хочу вернуть рецепты, содержащие только эти ингредиенты, и их подмножества, без рецепта, который может содержать один или несколько ингредиентов, которых у пользователя нет. – Kiki

Смежные вопросы