powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сложный запрос - определение вхождения подможества
10 сообщений из 10, страница 1 из 1
Сложный запрос - определение вхождения подможества
    #38632690
fourty
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Столкнулся с такой задачей и никак не пойму как ее решить. Запрос на самом деле очень большой, но теперь нужно его нагрузить еще и таким функционалом поэтому попытаюсь объяснить как можно проще.
Есть две таблицы. Первая таблица готовых блюд: id, название блюда, каллорийность и тд. Вторая таблица это ингридиенты блюд, соответственно id, название ингридиента, id_блюда.

Соответственно связь между ними такая:
Код: sql
1.
SELECT `блюда`.`id`, `блюда`.`название`, a.состав FROM `блюда` LEFT JOIN (SELECT ` id_блюда`, GROUP_CONCAT(`ингридиент`) AS состав  FROM `ингридиенты` GROUP BY ` id_блюда`) a ON a.`id_блюда`=`блюда`.`id`



Таким образом получаем что-то типа:
автор1 | Салат Цезарь| Курица, Сухарики, Салат и тд
2 | Борщ | Свекла, Чеснок, Морковь и тд

Задача состоит в том чтобы пользователь ввел ингридиенты которые у него есть, а в ответ получил возможные блюда. Важно чтобы состав продуктов блюда полностью являлся подмножеством продуктов пользователя.
Для простоты ингридиенты назовем латинскими маленькими буквами.
У пользователя есть продукты a, b, c, d
Блюда:
авторe
b
ac
acd
ace
abcd
abcde
Нам нужно показать выбрать:
авторb
ac
acd
abcd

Если идти в лоб, то нужно составить всевозможные комбинации продуктов пользователя выбирать через IN (). Можно ли как-то решить эту задачу более эффективно?

Заранее спасибо.
...
Рейтинг: 0 / 0
Сложный запрос - определение вхождения подможества
    #38632699
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fourty,

Код: sql
1.
2.
3.
4.
5.
select ид_блюда
from состав_блюд
where ид_ингредиента in (тут список через запятую)
group by 1
having count(*)>=(количество элементов списка)
...
Рейтинг: 0 / 0
Сложный запрос - определение вхождения подможества
    #38633602
fourty
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спаибо, но такой вариант не подходит. Вот пример:
авторБлюдо1. Состав a,b,c
Блюдо2. Состав: a, f

Запрос:
Код: sql
1.
2.
3.
4.
5.
select ид_блюда
from состав_блюд
where ид_ингредиента in (a,b,f,z)
group by 1
having count(*)>=2



Выборка получается из обоих блюд. Хотя для блюда1 не достаточно ингридиента c
...
Рейтинг: 0 / 0
Сложный запрос - определение вхождения подможества
    #38633693
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чтото нелогично в самом начале..

тоблиц должно быть три

Блюда(ид_блюда,название)
Ингридиенты(ид_ингредиента,название)

Рецепты(состав)
(ид_иблюда,ид_ингридиента)

или молоко для молочной каши гречневой, не тоже самое что молоко для манной каши???

и тогда получим алгоритм решения
1)найти ингридиенты которых нет
2)найти блюда которые нельзя приготовить
3)найти блюда которые не есть в списке 2


Код: sql
1.
2.
3.
4.
5.
6.
7.
ВЫБОР блюда.название 
ИЗ блюда
ГДЕ ид_блюда НЕ В --не в списке блюд=нельзя приготовить
    (ВЫБОР УНИКАЛЬНЫЕ ид_блюда ИЗ рецепты ГДЕ ид_ингридиента В -- в списке отсутсвующих
        (ВЫБОР ид_ингридиента ИЗ ингридиенты ГДЕ ид_ингридиента НЕ В (-список имеющихся)
        )
    ) 



решение ниже ..я не вникал, но похоже не верное, ибо в хевинг части условие предполагаемое, что рецепт блюда должен включать все имеющиеся ингридиенты, а в условия сказано подмножеством. тоесть блюдо стакан молока для ингридиентов молоко часнок чай сахар водка пиво тоже подходит, а решение его откинет
...
Рейтинг: 0 / 0
Сложный запрос - определение вхождения подможества
    #38633746
fourty
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex564657498765453, Спасибо огромное!!!
...
Рейтинг: 0 / 0
Сложный запрос - определение вхождения подможества
    #38634002
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fourtyХотя для блюда1 не достаточно ингридиента c Да, я не обратил внимание не требование полного подмножества. Тогда вот вариант без IN/NOT IN, авось побыстрее будет
Код: sql
1.
2.
3.
4.
select ид_блюда
from рецепты
group by 1
having count(*)=sum(case when ид_ингредиента in (a,b,f,z) then 1 else 0 end)
...
Рейтинг: 0 / 0
Сложный запрос - определение вхождения подможества
    #38634596
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglirfourtyХотя для блюда1 не достаточно ингридиента c Да, я не обратил внимание не требование полного подмножества. Тогда вот вариант без IN/NOT IN, авось побыстрее будет
Код: sql
1.
2.
3.
4.
select ид_блюда
from рецепты
group by 1
having count(*)=sum(case when ид_ингредиента in (a,b,f,z) then 1 else 0 end)



ты верно мыслишь, просто я в даной ситуации читер :) я учил скл по той же книге что и автор, и знаю что там речь идёт о базе данных санатория(столовой) и предполагаеться что на складе из скажем 1000 ингридиентов есть всё, закончилась редиска, может ещо прогнили кокосы... всё отальное есть. :)

а для написаной формулировки, аля база рецептур на кулинарном сайте, а петя хочет узнать что из тех остатков в его холодильнике можно забадяжить, возможно твой будет быстрее. :)
...
Рейтинг: 0 / 0
Сложный запрос - определение вхождения подможества
    #38634701
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а можно в MS SQL? суть не изменится, а перебивать в SQLFIDDLE лениво
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
;with ingridients as (
   select * from( values
      ('a'),('b'),('c'),('d')
   )values_product(ingr))
,recipe_header as (
   select * from( values
      (1),(2),(3),(4),(5),(6),(7)
   )values_recipe_header(id))
,recipe_details as (
   select * from( values
      (1,'e'),
      (2,'b'),
      (3,'f'),(3,'c'),
      (4,'a'),(4,'c'),(4,'d'),
      (5,'a'),(5,'c'),(5,'e'),
      (6,'a'),(6,'b'),(6,'c'),(6,'d'),
      (7,'a'),(7,'b'),(7,'c'),(7,'d'),(7,'e')
   )values_recipe_details(id,ingr))
select d.id
from recipe_header h
cross join ingridients i
right join recipe_details d on d.id=h.id and d.ingr=i.ingr
group by d.id
having COUNT(*)=COUNT(h.id)

id246
...
Рейтинг: 0 / 0
Сложный запрос - определение вхождения подможества
    #38635142
fourty
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglir , Спасибо. Этот вариант почти в 10 раз быстрее отрабатывает, чем у alex564657498765453. Нет, книга не та. Задача из реальной системы.
...
Рейтинг: 0 / 0
Сложный запрос - определение вхождения подможества
    #38635412
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fourty,

тогда да...я и писал что у тангира для другой ситуации быстрее... :) просто у тебя задача, а главное именование совпали с той книгой. :)
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сложный запрос - определение вхождения подможества
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]