MySQL使用group_concat将多个关系表选择为一行

时间:2019-02-01 00:52:54

标签: mysql join group-by group-concat

我有5个表:productCategory,products,productOptions,options,optionsGroup。我正在尝试做的是以某种方式将其合并并分组为一个查询,以返回包含有关一种产品的所有信息的一行。例如,某种类型的食物将具有不同的大小和风味。瓶子有不同的大小和气味。这些是表格:

productCategory

categoryId    categoryName
1             food
2             freshener

产品

productId    productCategoryRef    productName
1            1                     ....
2            1
3            2
4            2
FK references categoryId

productOptions

categoryRef  optionsRef
1            1
1            3
2            2
2            4
FK categoryRef references productCategory (categoryId)
FK optionsRef references options (optionsId)

选项

optionsId    optionsName
1            kg
2            ml
3            Flavor
4            Fragrance

optionsGroup

groupId    groupOptionRef  groupName
1          1               3
2          1               7
3          1               14
4          2               50
5          2               250
6          3               Chicken
7          3               Beef
8          4               Alpine
9          4               Berries
FK groupOptionRef references options (optionId)

因此,食品袋的重量可以为3kg,7kg或14kg,并可以具有两种不同的口味。我如何以可读格式将所有这些信息排成一行?这是我尝试过的:

SELECT 
  pc.*, p.*, 
  GROUP_CONCAT(DISTINCT o.optionsName) AS optionName, 
  GROUP_CONCAT(og.groupName) AS options 
FROM productCategories pc 
  JOIN products p ON p.productCategoryId=pc.categoryId 
  JOIN productOptions po ON po.categoryRef=pc.categoryId 
  JOIN options o ON o.optionsId=po.optionsRef 
  JOIN optionsGroup og ON og.groupOptionRef=o.optionsId 
WHERE p.productName=:itemName 
  GROUP BY p.productId

这给我一行

....
optionName: 'kg,Flavor',
options: '3,7,14,Chicken,Beef'
....

那是一团糟。是否有可能以某种方式将每个选项合并在一起,然后更容易地进行后处理,而不必猜测哪个部分达到kg / Flavor?

我知道这很容易,但是稍后会有一个评论部分,该部分将引用此productId,我也想加入此查询。任何建议都值得赞赏,如果需要的话,我愿意采用更好的数据库结构。

1 个答案:

答案 0 :(得分:1)

如果您不介意重复使用选项名称,则可以group_concat这样的concat:

GROUP_CONCAT(CONCAT(o.optionsName, ': ', og.groupName) ORDER BY o.optionsName, og.groupName) AS options 

如果您想要更多结构化的内容,则必须进行子查询(按选项名称分组,然后group_conc表示其组名称;然后在外部查询中不带选项名称进行分组);但是在那一点上,绝对值得考虑的是,您是否应该只处理客户端的格式设置和结果分组。