将多个子行组合成一行MYSQL

在此先感谢,我似乎无法得到它!

我有两张桌子

Ordered_Item

  ID | 项目名
 1 | 比萨
 2 | 斯特龙博利 

Ordered_Options

  Ordered_Item_ID |  Option_Number | 值
         1 43​​意大利辣香肠
         1 44额外的奶酪
         2 44额外的奶酪 

我正在寻找输出是一个MySQL查询是这样的效果

产量

  ID |  Item_Name |  Option_1 |  Option_2
 1个比萨辣香肠多余的奶酪
 2 Stromboli零额外的奶酪 

我已经尝试了多数选项最后在语法错误,我已经尝试了group_concat,但多数民众赞成但不是真正的我在找什么。 我认为可能是一个开始,下面有一个粗略的例子。 我需要每次select相同的顺序。 而在收集信息的程序中,没有办法可靠地确保将会发生。 是否可以根据选项号码进行连接? 另外我知道,我永远不会有超过5个选项,所以一个静态的解决scheme将工作

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; 

谢谢! 乔

最简单的方法就是在这里使用GROUP_CONCAT组函数。

 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; 

我感谢帮助,我认为我find了一个解决scheme,如果有人会评论我会感激的有效性。 基本上我所做的是。 我意识到它在实现上有些静态,但是我做了我需要的事情(原谅不正确的语法)

 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); 

你想要什么被称为一个数据透视表,它不是直接支持在MySQL中,检查这个答案了你的select:

如何转换一个MySQL实体 – 属性值模式

如果你的结果真的需要多列,而选项的数量是有限的,你甚至可以这样做:

 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 

如果你知道你将拥有有限数量的最大选项,那么我会尝试这个(每个订单最多4个选项的例子):

 selectOI.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 

按条件排除所有您将得到的副本。 我刚刚在我正在工作的网站上实现了类似的function,我知道在子表中我总是会有1或2个匹配的,我想确保每个父项只有1行。

这里是你如何构build你的查询这种types的需求。

 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”来“列出”每一列。 然后使用“group by”为每个预定项目select每个列的“max()”。