Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Задача: Один сложный запрос


Автор: CyberPulse 31.8.2013, 03:08
Доброй ночи. Вот уже третью ночь не могу спать нормально и мучает меня одна задача, которую я придумал сам для себя.

Введение: функционал как на сайте http://ogoloda.li/search, а именно мы выбираем список продуктов которые у нас есть и нам отображаются рецепты. Я не знаю как конкретно реализовано на данном сайте эта функция и никакого отношения не имею к этому ресурсу.

Условия:
1. нету ajax
2. для получения рецептов в базу можно послать только 1 запрос
3. создание временных таблиц нежелательно
4. Структура таблиц может быть любой

Как я вижу данную структуру (у вас может быть своя):
Таблица 1 - таблица с ингредиентами
Таблица 2 - таблица с рецептами
Таблица 3 - связывающая таблица  Таблицу 1 и Таблицу 2

P.S. Запрос я так и не придумал и не факт что такой запрос можно составить, но что-то мне подсказывает, что решение есть у этой задачи

Автор: Sanchezzz 1.9.2013, 09:09
Привет, надо начать со структуры вы ее придумали ?

здесь более полный мой ответ:
Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_5222da15ae201527428b66b2_0

Автор: Vladimir V 1.9.2013, 12:16
Sanchezzz прав.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_522305d0ae20159b6c2be1f1_0

Автор: CyberPulse 1.9.2013, 12:37
Цитата

   Например выбрать все рецепты которые содержат ингредиенты 1,23,44,66
   

я не совсем понял, а если в рецепте есть еще ингредиенты помимо 1,23,44,66 то такой же рецепт показывать не нужно, а при данном запросе он покажет такой рецепт

p.s. вообще привязываться к этому сайту не нужно и повторять структуру, вопрос больше теоретический чем практичекий

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_52230ad0ae20155f6e2be30b_0

Автор: ksnk 1.9.2013, 12:48
CyberPulse, Что за проблема-то? В такой комбинации таблиц получается долго и мутно.

Таблицы 
рецепты - recipe[id,Name,Description], 
ингридиенты ingredient[id,Name,Description], 
связь links[id,rId,iId]
ключики тривиальны и неинтересны

пришел набор ингридиентов в виде массива ID шек (таблица ingredient, получается, не нужна ;) ) величиной , к примеру,  5 штук.

Код

select * from recipe as r 
  join link as l1 on r.id=l1.rId
  join link as l2 on r.id=l2.rId
  join link as l3 on r.id=l3.rId
  join link as l4 on r.id=l4.rId
  join link as l5 on r.id=l5.rId
where
  l1.iId=:ID1
 and l2.iId=:ID2
 and l3.iId=:ID3
 and l4.iId=:ID4
 and l5.iId=:ID5

?

Автор: CyberPulse 1.9.2013, 13:18
я так понял, сколько ингредиентов столько и джойнов?

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_5223146aae2015856a2be7ca_0

Автор: Sanchezzz 1.9.2013, 13:38
Цитата

p.s. вообще привязываться к этому сайту не нужно и повторять структуру, вопрос больше теоретический чем практичекий

Не че страшного зато есть база отчего оттолкнутся.
Цитата

я так понял, сколько ингредиентов столько и джойнов?
 сорее всего да, я так раньше делал когда EAV прицеп БД использовал. 

Лучше тогда условия перебрать AND AND чем большое количество JOIN делать, скорее всего  быстрее будет. 



Автор: ksnk 1.9.2013, 13:45
Цитата(CyberPulse @  1.9.2013,  13:18 Найти цитируемый пост)
я так понял, сколько ингредиентов столько и джойнов?

Для такой организации таблиц - да.

Если в таблицу рецептов вставить поле с перечислением всех  ингридиентов через запятую (отсортированные по возрастанию ID), то для ЭТОЙ задачи получится простой запрос. 

Нужно понять, какие задачи решаются и для них (задач) смастерить правильную структура данных.

Автор: CyberPulse 1.9.2013, 13:58
Цитата

   Если в таблицу рецептов вставить поле с перечислением всех  ингридиентов через запятую (отсортированные по возрастанию ID), то для ЭТОЙ задачи получится простой запрос. 
   

мне кажется это не очень правильная структура базы

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_52231de4ae2015836a2becf4_0

Автор: CyberPulse 1.9.2013, 14:06
Способ от ksnk понравился, единственное не нравится изменяющийся кол-во джойнов, может есть еще какие идеи?

Цитата

   Нужно понять, какие задачи решаются и для них (задач) смастерить правильную структура данных.
   

задача - это составить красивый запрос с красивой структурой базы, на практике я понимаю что красиво не реализовать, либо пострадает производительность, потому задача - это сделать красиво

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_52231fc8ae20156c6d2be961_0

Автор: CyberPulse 1.9.2013, 14:42
http://sqlfiddle.com/#!2/8f274/4 посмотрите что я делаю не так, выдает только один рецепт, хотя по ингредиентам подходит два

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_52232835ae201562772be799_0

Автор: CyberPulse 1.9.2013, 14:54
Код

select * from recipe as r
  join link as l1 on r.id=l1.rId
  join link as l2 on r.id=l2.rId
  join link as l3 on r.id=l3.rId
  join link as l4 on r.id=l4.rId
  join link as l5 on r.id=l5.rId
where
  l1.iId=:ID1
and l2.iId=:ID2
and l3.iId=:ID3
and l4.iId=:ID4
and l5.iId=:ID5

как то не работает этот запрос

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_52232ae6ae201505192bda7e_0

Автор: ksnk 1.9.2013, 16:09
Вот http://sqlfiddle.com/#!2/d16f3/1 по ингридиентам подходит два

Автор: CyberPulse 1.9.2013, 19:49
А вот http://sqlfiddle.com/#!2/d16f3/3 тоже два рецепта, хотя должен быть один

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_52237028ae2015ad3f2be284_0

Автор: CyberPulse 1.9.2013, 20:12
результат запроса должен показать мне список рецептов, которые я могу приготовить из продуктов которые уже имеются

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_5223758bae20156f412be28e_0

Автор: ksnk 1.9.2013, 21:34
Цитата(CyberPulse @  1.9.2013,  20:12 Найти цитируемый пост)
результат запроса должен показать мне список рецептов, которые я могу приготовить из продуктов которые уже имеются


Вот так и надо было сразу написать smile

http://sqlfiddle.com/#!2/d4907/18
Если в наличии 3 продукта (1,2,3) - делается 2 блюда. Если 2 (2,3) - только одно.

Автор: CyberPulse 1.9.2013, 22:01
ksnk, блин +10 в карму, я думал о током алгоритме, но плохо знаю синтаксис SQL, думал нельзя так сделать :)

В принципе задача решена, всем спасибо)

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//Задача-Один-сложный-запрос-id5221341fae2015114c8b4567#findElement_E7045_52238f24ae2015e6542be08a_0

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)