MySQL – GROUP_CONCAT返回重复数据,不能使用DISTINCT
作者:互联网
我有一个规范化的数据库,我正在尝试使用JOIN和GROUP_CONCAT从多个表返回数据.
问题:使用GROUP_CONCAT复制行.我不能使用DISTINCT,因为某些数据(成分mfr)确实需要重复.
这是我当前的查询和数据库结构(SQL Fiddle):
SELECT recipe.*,
GROUP_CONCAT(recipe_detail.ingredient_id) AS iid,
GROUP_CONCAT(ingredient.name) AS iname,
GROUP_CONCAT(ingredient_mfr.abbr) AS mabbr,
GROUP_CONCAT(recipe_tag.name) AS tag
FROM recipe
LEFT JOIN recipe_detail
ON recipe.id = recipe_detail.recipe_id
LEFT JOIN ingredient
ON recipe_detail.ingredient_id = ingredient.id
LEFT JOIN ingredient_mfr
ON ingredient.mfr_id = ingredient_mfr.id
LEFT JOIN recipe_tagmap
ON recipe.id = recipe_tagmap.recipe_id
LEFT JOIN recipe_tag
ON recipe_tagmap.tag_id = recipe_tag.id
WHERE recipe.user_id = 1
GROUP BY recipe.id
recipe
+------------+------------+-----------+
| id | name | user_id |
+============+============+===========+
| 1 | Test123 | 1 |
+------------+------------+-----------+
| 2 | Test456 | 1 |
+------------+------------+-----------+
| 3 | Test789 | 1 |
+------------+------------+-----------+
recipe_detail
+------------+---------------+
| recipe_id | ingredient_id |
+============+===============+
| 1 | 193 |
+------------+---------------+
| 1 | 194 |
+------------+---------------+
| 2 | 16 |
+------------+---------------+
| 3 | 277 |
+------------+---------------+
ingredient
+------------+---------------+---------+
| id | name | mfr_id |
+============+===============+=========+
| 16 | Gin | 4 |
+------------+---------------+---------+
| 193 | Fig | 3 |
+------------+---------------+---------+
| 194 | Tea | 3 |
+------------+---------------+---------+
| 277 | Nut | 2 |
+------------+---------------+---------+
ingredient_mfr
+------------+------------+
| id | abbr |
+============+============+
| 2 | TFA |
+------------+------------+
| 3 | FA |
+------------+------------+
| 4 | LOR |
+------------+------------+
recipe_tag
+------------+------------+
| id | name |
+============+============+
| 1 | one |
+------------+------------+
| 2 | two |
+------------+------------+
| 3 | three |
+------------+------------+
| 4 | four |
+------------+------------+
| 5 | five |
+------------+------------+
| 6 | six |
+------------+------------+
| 7 | seven |
+------------+------------+
| 8 | eight |
+------------+------------+
| 9 | nine |
+------------+------------+
recipe_tagmap
+------------+---------------+---------+
| id | recipe_id | tag_id |
+============+===============+=========+
| 1 | 1 | 1 |
+------------+---------------+---------+
| 2 | 1 | 2 |
+------------+---------------+---------+
| 3 | 1 | 3 |
+------------+---------------+---------+
| 4 | 2 | 4 |
+------------+---------------+---------+
| 5 | 2 | 5 |
+------------+---------------+---------+
| 6 | 2 | 6 |
+------------+---------------+---------+
| 7 | 3 | 7 |
+------------+---------------+---------+
| 8 | 3 | 8 |
+------------+---------------+---------+
| 9 | 3 | 9 |
+------------+---------------+---------+
使用我当前的查询,我的结果如下所示:
+------+---------+--------------+----------- ----+---------------+------------------+
| id | name | iid | iname | mabbr | tag |
+======+=========+==============+================+===============+==================+
| 1 | Test123 | 193,193,193, | Fig, Fig, Fig, | FA, FA, FA, | one, two, three, |
| | | 194,194,194 | Tea, Tea, Tea | FA, FA, FA | one, two, three |
+------+---------+--------------+----------------+---------------+------------------+
| 2 | Test456 | 16,16,16 | Gin, Gin, Gin | LOR, LOR, LOR | four, five six |
+------+---------+--------------+----------------+---------------+------------------+
| 3 | Test789 | 277,277,277 | Nut, Nut, Nut | TFA, TFA, TFA | seven,eight,nine |
+------+---------+--------------+----------------+---------------+------------------+
我希望我的结果如下:
+------+---------+--------------+----------- ----+---------------+------------------+
| id | name | iid | iname | mabbr | tag |
+======+=========+==============+================+===============+==================+
| 1 | Test123 | 193, 194 | Fig, Tea | FA, FA | one, two, three, |
+------+---------+--------------+----------------+---------------+------------------+
| 2 | Test456 | 16 | Gin | LOR | four, five six |
+------+---------+--------------+----------------+---------------+------------------+
| 3 | Test789 | 277 | Nut | TFA | seven,eight,nine |
+------+---------+--------------+----------------+---------------+------------------+
如您所见,多个标签的存在会导致配料数据重复.多种成分的存在导致标签复制.我曾试图使用DISTINCT,但有时我会有多种成分,其中每一种都会返回它自己的“mabbr”,这可能与它的其他成分相同(见第一行预期结果).使用DISTINCT,它只返回该“mabbr”的一个实例.
我可以对我的查询进行更改以实现我想要做的事情吗?
解决方法:
您已经确定了问题的根源:该配方连接到两个表,recipe_detail和recipe_tagmap(以及这些表分别与“成分”和“标签”相关的其他几个表),并且配方与一对多关系他们都.
一种解决方案是单独GROUP BY并首先聚合(一个聚合用于与成分相关的表列表,另一个聚合用于与标签相关的表组,然后再联接(再次)到主表(配方):
SELECT recipe.*,
iid,
iname,
mabbr,
tag
FROM recipe
LEFT JOIN
( SELECT recipe_detail.recipe_id,
GROUP_CONCAT(recipe_detail.ingredient_id) AS iid,
GROUP_CONCAT(ingredient.name) AS iname,
GROUP_CONCAT(ingredient_mfr.abbr) AS mabbr
FROM recipe
JOIN recipe_detail
ON recipe.id = recipe_detail.recipe_id
LEFT JOIN ingredient
ON recipe_detail.ingredient_id = ingredient.id
LEFT JOIN ingredient_mfr
ON ingredient.mfr_id = ingredient_mfr.id
WHERE recipe.user_id = 1
GROUP BY recipe_detail.recipe_id
) AS details
ON recipe.id = details.recipe_id
LEFT JOIN
( SELECT recipe_tagmap.recipe_id,
GROUP_CONCAT(recipe_tag.name) AS tag
FROM recipe
JOIN recipe_tagmap
ON recipe.id = recipe_tagmap.recipe_id
LEFT JOIN recipe_tag
ON recipe_tagmap.tag_id = recipe_tag.id
WHERE recipe.user_id = 1
GROUP BY recipe_tagmap.recipe_id
) AS tags
ON recipe.id = tags.recipe_id
WHERE recipe.user_id = 1 ;
测试时间:SQL-Fiddle
(并不严格使用2个聚合中的配方表,但由于您只需要一个用户的配方,因此它将有助于提高效率,限制从多个表中检索并聚合的行数.)
标签:mysql,join,duplication,group-concatenation 来源: https://codeday.me/bug/20190806/1596968.html