Идентификатор совпадения MYSQL с ключевыми словами столбца и отображение результатов

У меня есть база данных с сотнями тортов и разными ключевыми словами для каждого торта. В этом примере я хочу сначала сопоставить торты, которые имеют как минимум 2 похожих ключевых слова - в этом примере это будут торты 1 и 4. (Не знаю, как сделать здесь таблицу, но я перечислил идентификаторы 1- 4, а затем колонка под названием ингредиенты, которая показывает три ингредиента для каждого идентификатора.) И затем я хочу показать их. Звучит достаточно просто, но я пока безуспешно. Любая помощь приветствуется.

Название стола:десерты

id ингредиенты
1-- помадка, карамель, кокос-- 2. ваниль, фундук, кокос-- 3. ваниль, шоколад, помадка-- 4. помадка, карамель, ваниль--

По сути, я хочу показать все торты, которые состоят из двух или более одинаковых ингредиентов. Не уверен, как сделать запрос.


person JJM    schedule 21.05.2013    source источник
comment
Что вы пробовали? Какая у вас схема БД? Если вы перечисляете ингредиенты в поле своей базы данных тортов, вы делаете это очень неправильно...   -  person Laurent S.    schedule 21.05.2013
comment
Вам будет намного легче написать запрос для этой проблемы, если вы не поместите в свою таблицу значения, разделенные запятыми. Идеальная схема должна иметь отдельную таблицу под названием «ингредиенты» со столбцом «dessert_id».   -  person Blaise Swanwick    schedule 21.05.2013
comment
Все значения разделяются запятой, например, помадка, карамель, кокос. Как я могу работать с тем, что у меня есть?   -  person JJM    schedule 21.05.2013


Ответы (2)


Это действительно ужасный дизайн базы данных, и правильный ответ — изменить его. В идеале у вас должны быть отдельные таблицы для тортов и ингредиентов, а затем третья, чтобы связать идентификаторы тортов с идентификаторами ингредиентов.

Но предполагая, что торты всегда состоят из трех ингредиентов, вы можете, хотя и не должны этого делать:

SELECT DISTINCT id
FROM (SELECT id, SUBSTRING_INDEX(ingredients,',',1) AS ingredient FROM cakes
     UNION
     SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(ingredients,',',-2),',',1) AS ingredient FROM cakes
     UNION
     SELECT id, SUBSTRING_INDEX(ingredients,',',-1) AS ingredient FROM cakes) AS i
GROUP BY ingredient
HAVING count(*) >= 2

Он использует вложенный выбор для создания трех таблиц ингредиентов, по одной для каждой отдельной позиции запятой, которые объединяются как UNION. Когда у вас есть эта информация, вам остается только сгруппировать пирожные по их ингредиентам и отфильтровать те ингредиенты, которые не использовались более одного раза (пункт HAVING). Это оставляет вам список идентификаторов тортов, которые содержат неуникальные ингредиенты.

Это ужасное решение, и оно не будет работать, если у вас есть пирожные с четырьмя или более ингредиентами, хотя вы можете добавить больше операторов UNION для учета большего количества возможных ингредиентов, если нет возможности изменить структуру базы данных.

person Rebecka    schedule 21.05.2013
comment
Спасибо! Я попробую так и правильно (три таблицы). Я просто не был уверен, как сделать третью таблицу, которая связывает идентификаторы торта с идентификаторами ингредиентов. - person JJM; 21.05.2013
comment
ты хотел написать КАК ингредиент ОТ пирожных) КАК я? близко к концу? - person JJM; 21.05.2013
comment
Я сделал. AS ingredient FROM cakes — это просто заключение оператора SELECT, ) — закрыть подзапрос (соответствующий ( после FROM), наконец, AS i — это потому, что при построении таблицы в подзапросе вам нужно присвоить ей псевдоним. Обычно вы присоединяетесь к подвыборке с другой таблицей, поэтому вам нужен способ сослаться на нее, но даже если здесь это не нужно, MySQL выдаст ошибку без нее. - person Rebecka; 21.05.2013

@Michael - совершенно правильно, что касается трех столов, тортов, ингредиентов и cakes_ingredients_rel.

  • В торте много ингредиентов
  • Ингредиент можно использовать во многих тортах

Это отношение многие ко многим.

Поэтому таблица взаимосвязей используется для сопоставления тортов с ингредиентами:

CAKES_INGREDIENTS_REL
id
cakes_id
ingredients_id
person Tom Wilson    schedule 08.02.2015