MySQL 使用 group_concat 选择多个关系表到一行
MySQL selecting multiple relational tables into one row with group_concat
我有 5 个表:productCategory、products、productOptions、options、optionsGroup。我想做的是以某种方式将它们连接起来并将它们组合成一个查询 return 一行,其中包含有关一种产品的所有信息。例如,某种食物会有不同的大小和不同的味道;瓶子有不同的大小和气味。以下是表格:
产品类别
categoryId categoryName
1 food
2 freshener
产品
productId productCategoryRef productName
1 1 ....
2 1
3 2
4 2
FK references categoryId
产品选项
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
选项组
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)
所以一个食品袋可以是3公斤、7公斤或14公斤,可以有两种不同的口味。我怎样才能以可读的格式在一行中获取所有这些信息?这是我的尝试:
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'
....
一团糟。是否有可能以某种方式将每个选项连接在一起,然后 post- 处理起来更容易,而不必猜测哪个部分进入 kg/Flavor?
我知道这里会很容易,但稍后会有一个评论部分将引用此 productId,我也想将其加入此查询。任何建议表示赞赏,如果需要的话,我愿意接受更好的数据库结构。
如果您不介意重复选项名称,您可以 group_concat 像这样的连接:
GROUP_CONCAT(CONCAT(o.optionsName, ': ', og.groupName) ORDER BY o.optionsName, og.groupName) AS options
如果您想要比这更结构化,则必须进行子查询(按选项名称分组,然后 group_concat 对其分组名称;然后在外部查询中不使用选项名称进行分组);但此时绝对值得考虑是否应该只在客户端处理格式化和分组结果。
我有 5 个表:productCategory、products、productOptions、options、optionsGroup。我想做的是以某种方式将它们连接起来并将它们组合成一个查询 return 一行,其中包含有关一种产品的所有信息。例如,某种食物会有不同的大小和不同的味道;瓶子有不同的大小和气味。以下是表格:
产品类别
categoryId categoryName
1 food
2 freshener
产品
productId productCategoryRef productName
1 1 ....
2 1
3 2
4 2
FK references categoryId
产品选项
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
选项组
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)
所以一个食品袋可以是3公斤、7公斤或14公斤,可以有两种不同的口味。我怎样才能以可读的格式在一行中获取所有这些信息?这是我的尝试:
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'
....
一团糟。是否有可能以某种方式将每个选项连接在一起,然后 post- 处理起来更容易,而不必猜测哪个部分进入 kg/Flavor?
我知道这里会很容易,但稍后会有一个评论部分将引用此 productId,我也想将其加入此查询。任何建议表示赞赏,如果需要的话,我愿意接受更好的数据库结构。
如果您不介意重复选项名称,您可以 group_concat 像这样的连接:
GROUP_CONCAT(CONCAT(o.optionsName, ': ', og.groupName) ORDER BY o.optionsName, og.groupName) AS options
如果您想要比这更结构化,则必须进行子查询(按选项名称分组,然后 group_concat 对其分组名称;然后在外部查询中不使用选项名称进行分组);但此时绝对值得考虑是否应该只在客户端处理格式化和分组结果。