[英]Combine Multiple child rows into one row MYSQL
Thanks in advance, I just can't seem to get it! 在此先感谢,我似乎无法理解!
I have two tables 我有两张桌子
Ordered_Item Ordered_Item
ID | Item_Name 1 | Pizza 2 | Stromboli
Ordered_Options Ordered_Options
Ordered_Item_ID | Option_Number | Value 1 43 Pepperoni 1 44 Extra Cheese 2 44 Extra Cheese
What I am looking to output is a mysql query is something to this effect 我想要输出的是mysql查询,可以达到这种效果
Output 输出量
ID | Item_Name | Option_1 | Option_2 1 Pizza Pepperoni Extra Cheese 2 Stromboli NULL Extra Cheese
I have tried numerous options most ending in syntax error, I have tried group_concat but thats not really what I am looking for. 我尝试了很多选项,大多数以语法错误结尾,我尝试了group_concat,但这并不是我真正想要的。 I have a crude example below of what I think might be a start.
下面有一个简单的例子,我认为这可能是一个开始。 I need the options to be in the same order every time.
我需要选项每次都按相同顺序排列。 And in the program where the info is collected there is no way to reliable ensure that will happen.
在收集信息的程序中,没有办法可靠地确保将要发生。 Is it possible to have them concatenate according to option number.
是否可以根据选件号将它们连接在一起。 Also I know that I will never have over 5 options so a static solution would work
我也知道我永远不会有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;
Thanks! 谢谢! Joe
乔
The easiest way would be to make use of the GROUP_CONCAT group function here.. 最简单的方法是在这里使用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
Which would output: 哪个会输出:
Id ItemName Options
1 Pizza Pepperoni,Extra Cheese
2 Stromboli Extra Cheese
That way you can have as many options as you want without having to modify your query. 这样,您可以根据需要选择多个选项,而无需修改查询。
Ah, if you see your results getting cropped, you can increase the size limit of GROUP_CONCAT like this: 嗯,如果您看到结果被裁剪,可以像下面这样增加GROUP_CONCAT的大小限制:
SET SESSION group_concat_max_len = 8192;
I appreciate the help, I do think I have found a solution if someone would comment on the effectiveness I would appreciate it. 我很感谢您的帮助,如果有人对我的效果表示赞赏,我认为我已经找到了解决方案。 Essentially what I did is.
本质上,我所做的就是。 I realize it is somewhat static in its implementation but I does what I need it to do (forgive incorrect syntax)
我意识到它的实现有些静态,但是我做了我需要做的事情(原谅不正确的语法)
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);
If you really need multiple columns in your result, and the amount of options is limited, you can even do this: 如果您的结果中确实需要多列,并且选项数量有限,则可以执行以下操作:
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
What you want is called a pivot, and it's not directly supported in MySQL, check this answer out for the options you've got: 您想要的东西称为枢轴,而MySQL并不直接支持它,请查看此答案以了解您拥有的选项:
How to pivot a MySQL entity-attribute-value schema 如何透视MySQL实体-属性-值架构
If you know you're going to have a limited number of max options then I would try this (example for max of 4 options per order): 如果您知道有限数量的最大选项,那么我会尝试一下(例如每个订单最多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
The group by condition gets rid of all of the duplicates that you would otherwise get. 按条件分组将消除您原本可以得到的所有重复项。 I've just implemented something similar on a site I'm working on where I knew I'd always have 1 or 2 matched in my child table, and I wanted to make sure I only had 1 row for each parent item.
我刚刚在我正在工作的网站上实现了类似的操作,我知道我的子表中总是有1或2个匹配项,并且我想确保每个父项只有1行。
Here is how you would construct your query for this type of requirement. 这是您针对此类需求构造查询的方式。
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;
You basically "case out" each column using case when
, then select the max()
for each of those columns using group by
for each intended item. 基本上,您可以在
case when
使用case when
“区分”每一列,然后使用group by
为每个预期的项目选择每个列的max()
。
Joe Edel's answer to himself is actually the right approach to resolve the pivot problem. Joe Edel对自己的回答实际上是解决关键问题的正确方法。
Basically the idea is to list out the columns in the base table firstly, and then any number of options.value
from the joint option table. 基本上,这个想法是首先列出基表中的列,然后列出联合选项表中的任意数量的
options.value
。 Just left join
the same option table multiple times in order to get all the options. 刚
left join
,多次联接同一选项表即可获得所有选项。
What needs to be done by the programming language is to build this query dynamically according to a list of options needs to be queried. 编程语言需要做的是根据需要查询的选项列表动态构建此查询。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.