所以我有一个数据库,有很多多对多关系。 我有一个主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的查询,如下所示(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
在组连接中得到重复的结果,例如类:'Class1',Class1',
或classrole:'Class1,Class1,Class1'
。 这是什么原因?我该如何修复它?
最简单的解决方案是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;
这将具有更好的性能,特别是如果基础表的索引设置正确的话。