group concat产生重复

n1bvdmb6  于 2021-07-29  发布在  Java
关注(0)|答案(1)|浏览(381)

所以我有一个数据库,有很多对很多的关系。我有我的主菜 items 一张table class 一张table和一张table class_role table。一个项可以有多个类和类角色。我想要的结果是这样的:

[{
  ItemId: ...,
  Name: ...,
  Classes: 'Class1, Class2, Class3',
  ClassRoles: 'ClassRole1, ClassRole2'
}...]

我目前的方法是使用如下关系表: r_items_classes (Itemid, ClassId), r_items_class_roles (Itemid, ClassRoleId) 然后用groupconcat和groupby这样的查询( Class 以及 ClassRole 只是对应表中相应的“名称”字段):

SELECT items.ItemId, items.Name, GROUP_CONCAT(Class) as Classes FROM items
JOIN r_items_classes ON items.ItemId = r_items_classes.ItemId
JOIN classes ON r_items_classes.ClassId = classes.ClassId
GROUP BY items.Itemid, items.Name

现在,这对于多对多关系中的一种来说是完美的。但是,当我添加另一个类似的示例时:

SELECT items.ItemId, items.Name, GROUP_CONCAT(Class) as Classes, GROUP_CONCAT(ClassRole) as ClassRoles FROM items
JOIN r_items_classes ON items.ItemId = r_items_classes.ItemId
JOIN classes ON r_items_classes.ClassId = classes.ClassId
JOIN r_items_class_roles ON items.ItemId = r_items_class_roles.ItemId
JOIN class_roles ON r_items_class_roles.ClassRoleId = class_roles.ClassRoleId
GROUP BY items.Itemid, items.Name

例如,我在concats组中得到了重复的结果 Classes: 'Class1, Class1, Class2' 或者 ClassRoles: 'ClassRole1, ClassRole1, ClassRole1' . 原因是什么?我该怎么解决?

lyfkaqu1

lyfkaqu11#

最简单的解决办法是 DISTINCT :

SELECT items.ItemId, items.Name, GROUP_CONCAT(DISTINCT Class) as Classes,
       GROUP_CONCAT(DISTINCT ClassRole) as ClassRoles

但是,通过预聚合或使用子查询,单独执行每个连接可能会更有效。
所以,这可能更有效:

select i.*,
       (select group_concat(c.class)
        from r_items_classes ic join
             classes c
             on ic.ClassId = c.ClassId
        where i.ItemId = ic.ItemId
       ) as classes,
       (select group_concat(cr.ClassRole)
        from r_items_class_roles icr join
             class_roles cr
             on icr.ClassId = cr.ClassId
        where i.ItemId = icr.ItemId
       ) as ClassRoles
from items i;

这将有更好的性能,特别是如果基础表的索引设置正确的话。

相关问题