提问者:小点点

多个多对多关系上的组连接ship连接会产生重复项


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

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

我当前的方法是使用如下关系表:r_items_class(Itemid,ClassId),r_items_class_roles(Itemid,ClassRoleId),然后使用具有GROUP_CONCAT和GROUP_BY的查询,如下所示(classclassrole只是相应表中各自的“名称”字段):

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

在组连接中得到重复的结果,例如类:'Class1',Class1',classrole:'Class1,Class1,Class1'。 这是什么原因?我该如何修复它?


共1个答案

匿名用户

最简单的解决方案是distinction:

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;

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