Объединить несколько дочерних строк в одну строку MYSQL

Заранее спасибо, я просто не могу это понять!

У меня две таблицы

Ordered_Item

ID | Item_Name
1  | Pizza
2  | Stromboli

Ordered_Options

Ordered_Item_ID | Option_Number | Value
        1               43         Pepperoni
        1               44         Extra Cheese
        2               44         Extra Cheese

То, что я с нетерпением жду вывода, является запрос MySQL что-то на этот счет

Output

ID | Item_Name | Option_1 | Option_2
1    Pizza       Pepperoni  Extra Cheese
2    Stromboli     NULL     Extra Cheese

Я пробовал многочисленные варианты, большинство из которых заканчивалось синтаксической ошибкой, я пробовал group_concat, но это не совсем то, что я ищу. У меня есть грубый пример ниже того, что я думаю, может быть началом. Мне нужно, чтобы варианты были в одном и том же порядке каждый раз. И в программе, где собирается информация, нет надежного способа гарантировать, что это произойдет. Можно ли их объединить в соответствии с номером опции. Также я знаю, что у меня никогда не будет более 5 вариантов, поэтому будет работать статическое решение

Select Ordered_Items.ID,
    Ordered_Items.Item_Name,
FROM Ordered_Items
    JOIN (SELECT Ordered_Options.Value FROM Ordered_Options Where Option_Number = 43) as Option_1 
        ON Ordered_Options.Ordered_Item_ID = Ordered_Item.ID
    JOIN (SELECT Ordered_Options.Value FROM Ordered_Options Where Option_Number = 44) as Option_2 
        ON Ordered_Options.Ordered_Item_ID = Ordered_Item.ID;

Спасибо! Джо

Ответы на вопрос(6)

я думаю, что я нашел решение, если бы кто-то прокомментировал эффективность, я был бы признателен за это. По сути, я сделал это. Я понимаю, что он несколько статичен в своей реализации, но я делаю то, что мне нужно (простите за неправильный синтаксис)

SELECT
  ordered_item.id as `Id`,
  ordered_item.Item_Name as `ItemName`,
  Options1.Value
  Options2.Value
FROM ORDERED_ITEMS
LEFT JOIN (Ordered_Options as Options1)
    ON (Options1.Ordered_Item.ID = Ordered_Options.Ordered_Item_ID 
        AND Options1.Option_Number = 43)
LEFT JOIN (Ordered_Options as Options2)
    ON (Options2.Ordered_Item.ID = Ordered_Options.Ordered_Item_ID
        AND Options2.Option_Number = 44);
 01 июл. 2009 г., 13:52
Это будет трудно поддерживать. Рано или поздно ваш клиент захочет иметь третий или четвертый вариант, и к тому времени вам придется все переписать.
 01 июл. 2009 г., 13:58
Добавлен другой ответ, который дает те же результаты, что и запрос, который вы опубликовали, но он немного более гибкий. Вы по-прежнему можете иметь неограниченное количество вариантов, в то же время получая несколько столбцов для вариантов пиццы в вашем результате.

что вы хотите, называется сводной, и она не поддерживается напрямую в MySQL. Проверьте этот ответ, чтобы узнать, какие опции у вас есть:

Как повернуть схему значения атрибута сущности MySQL

что у вас будет ограниченное количество макс. Опций, я бы попробовал это (пример для макс. 4 опций на заказ):

Select OI.ID, OI.Item_Name, OO1.Value, OO2.Value, OO3.Value, OO4.Value

FROM Ordered_Items OI
    LEFT JOIN Ordered_Options OO1 ON OO1.Ordered_Item_ID = OI.ID
    LEFT JOIN Ordered_Options OO2 ON OO2.Ordered_Item_ID = OI.ID AND OO2.ID != OO1.ID
    LEFT JOIN Ordered_Options OO3 ON OO3.Ordered_Item_ID = OI.ID AND OO3.ID != OO1.ID AND OO3.ID != OO2.ID
    LEFT JOIN Ordered_Options OO4 ON OO4.Ordered_Item_ID = OI.ID AND OO4.ID != OO1.ID AND OO4.ID != OO2.ID AND OO4.ID != OO3.ID

GROUP BY OI.ID, OI.Item_Name

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

select ID,Item_Name,max(Flavor) as Flavor,max(Extra_Cheese) as Extra_Cheese
    from (select i.*,
                    case when o.Option_Number=43 then o.value else null end as Flavor,
                    case when o.Option_Number=44 then o.value else null end as Extra_Cheese
                from Ordered_Item i,Ordered_Options o) a
    group by ID,Item_Name;

Вы в основном "из дела" каждый столбец с использованиемcase whenзатем выберитеmax() для каждого из этих столбцов, используяgroup by для каждого намеченного пункта.

select
  ordered_item.id as `Id`,
  ordered_item.Item_Name as `ItemName`,
  GROUP_CONCAT(Ordered_Options.Value) as `Options`
from
  ordered_item,
  ordered_options
where
  ordered_item.id=ordered_options.ordered_item_id
group by
  ordered_item.id

Что бы вывести:

Id              ItemName       Options

1               Pizza          Pepperoni,Extra Cheese

2               Stromboli      Extra Cheese

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

Ах, если вы видите, что ваши результаты обрезаются, вы можете увеличить ограничение размера GROUP_CONCAT следующим образом:

SET SESSION group_concat_max_len = 8192;
 01 июл. 2009 г., 07:45
он сказал & quot; Я пробовал group_concat, но это не совсем то, что я ищу. & Quot;
 20 февр. 2019 г., 08:07
Это действительно хорошо, позвольте мне проверить
 01 июл. 2009 г., 13:48
Чтобы упорядочить элементы в группе, вы можете сделать это, например: GROUP_CONCAT (Ordered_Options.Value ORDER BY Ordered_Options.value),
 01 июл. 2009 г., 08:03
Здравствуйте, спасибо за быстрый ответ, но, боюсь, я не включил важную информацию. Мне нужно, чтобы варианты были в одном и том же порядке каждый раз. И в программе, где собирается информация, нет надежного способа гарантировать, что это произойдет. Можно ли их объединить в соответствии с номером опции. Также я знаю, что у меня никогда не будет более 5 вариантов, поэтому будет работать статическое решение.

а количество вариантов ограничено, вы даже можете сделать это:

select
  ordered_item.id as `Id`,
  ordered_item.Item_Name as `ItemName`,
  if(ordered_options.id=1,Ordered_Options.Value,null) as `Option1`,
  if(ordered_options.id=2,Ordered_Options.Value,null) as `Option2`,
  if(ordered_options.id=43,Ordered_Options.Value,null) as `Option43`,
  if(ordered_options.id=44,Ordered_Options.Value,null) as `Option44`,
  GROUP_CONCAT(if(ordered_options.id not in (1,2,43,44),Ordered_Options.Value,null)) as `OtherOptions`
from
  ordered_item,
  ordered_options
where
  ordered_item.id=ordered_options.ordered_item_id
group by
  ordered_item.id

Ваш ответ на вопрос