#mysql #sql
#mysql #sql
Вопрос:
У меня есть таблица ингредиентов:
ing_id, ing_name
1 , ing1
...
таблица рецептов:
rec_id, rec_name
1 , rec1
...
и таблица, показывающая связь между этими двумя:
id, ing_id, rec_id
1, 1, 1
2, 1, 2
3, 2, 1
4, 3, 3
...
Как я могу найти ингредиенты, которые чаще всего используются в одном и том же рецепте?
Комментарии:
1. Что вы подразумеваете под словом «чаще всего»? Вы думаете о том, чтобы перечислить комбинацию ингредиентов и их количество по рецепту? Если в рецепте есть 3 ингредиента, это будет считаться ing1 2, ing1 3, ing2 3. Если в рецепте 4 ингредиента, это будет подсчет ing1 2, ing1 3, ing1 4, ing2 3, ing2 4, ing3 4, ing1 2 3, ing1 2 4, ing1 3 4 и т.д., а затем сортировка по наибольшемусначала посчитайте. Это то, чего ты хочешь?
2. Обновил пример, чтобы лучше проиллюстрировать проблему: в приведенном выше примере ингредиенты 1 и 2 имеют один общий рецепт (rec_id = 1), в то время как ингредиенты 1 и 3 не имеют общего рецепта. То же самое для ингредиентов 2 и 3. Таким образом, мы хотели бы, чтобы результат был равен 1 и 2, поскольку это комбинация с наиболее распространенными рецептами (один> ноль).
3. Допустим, у вас было 5 разных рецептов.
Recipe1
имел ингредиенты i1, i2 и i3.Recipe2
имел i1, i2, i3, i4, i5.Recipe3
имел i3, i4, i7, i8.Recipe4
имел i3, i4, i5, i6, i7, i9, i10.Recipe5
были все ингредиенты i1 ..i10. Как будет выглядеть ваш вывод?4. 3 и 4. Они оба появляются вместе в четырех рецептах (2,3,4,5), что выше, чем у любой другой пары ингредиентов.
5. Вам лучше выполнять эту математику вне SQL на языке программирования по вашему выбору. В приведенном выше примере, если бы i2 был в тех же рецептах, что и i3, вы бы хотели получить выходные данные i2, i3 и i4. Это означает, что вы хотите увидеть, какая комбинация ингредиентов из 2 чаще всего встречается во всех рецептах.
Ответ №1:
Вы можете использовать самосоединение и group by
:
select c1.ing_id, c2.ing_id, count(*)
from connections c1 join
connections c2
on c1.rec_id = c2.rec_id and c1.ing_id < c2.ing_id
group by c1.ing_id, c2.ing_id
order by count(*) desc;
Если вам действительно нужны имена вместо идентификаторов, вам понадобятся еще два соединения, чтобы ввести их.
Комментарии:
1. Это намного проще, чем я думал!