MySQL电子书库查询多作者多主题时GROUP_CONCAT结果重复问题求助
问题原因
你遇到的重复是多对多关系关联后产生笛卡尔积导致的:当一本图书同时关联N个作者、M个主题时,两张关联表同时Join后会生成N*M条中间数据,直接拼接就会出现重复值。
解决方案1:快速去重(适合小数据量)
直接在GROUP_CONCAT中加入DISTINCT关键字去除重复值即可,修改后的代码如下:
SELECT e.id, e.title, GROUP_CONCAT(DISTINCT a.full_name) AS author, GROUP_CONCAT(DISTINCT t.theme_name) AS themes FROM ebooks e JOIN ebooks_authors ea ON e.id = ea.ebook_id JOIN authors a ON a.id = ea.author_id JOIN ebooks_themes et ON e.id = et.ebook_id JOIN theme t ON t.id = et.theme_id GROUP BY e.id, e.title;
注意按照SQL规范,GROUP BY需要包含所有非聚合的查询字段,这里补充了e.title避免新版本MySQL报错。
解决方案2:预聚合后关联(适合大数据量,效率更高)
先分别聚合每个图书对应的作者和主题,再关联主表,避免先生成大量笛卡尔积中间数据:
SELECT e.id, e.title, IFNULL(auth.authors, '') AS author, IFNULL(thm.themes, '') AS themes FROM ebooks e -- 关联预聚合好的作者数据 LEFT JOIN ( SELECT ea.ebook_id, GROUP_CONCAT(a.full_name) AS authors FROM ebooks_authors ea JOIN authors a ON ea.author_id = a.id GROUP BY ea.ebook_id ) auth ON e.id = auth.ebook_id -- 关联预聚合好的主题数据 LEFT JOIN ( SELECT et.ebook_id, GROUP_CONCAT(t.theme_name) AS themes FROM ebooks_themes et JOIN theme t ON et.theme_id = t.id GROUP BY et.ebook_id ) thm ON e.id = thm.ebook_id -- 过滤掉没有作者也没有主题的图书,如果不需要可以删掉下面这行 WHERE auth.ebook_id IS NOT NULL OR thm.ebook_id IS NOT NULL;
这个方案还支持查询只有作者没有主题、或者只有主题没有作者的图书,适用场景更广泛。
内容的提问来源于stack exchange,提问作者HerrK
相关产品推荐
相关产品推荐

