我有4个表,组,成员,人和属性。
组
GroupID
GroupName
ParentGroupID
成员
PersonID
GroupID
人
PersonID
Name
属性
AttributeID
GroupID
Value
属性分配给组,组通过成员资格表分配人员。
我想显示与特定人士相关的所有属性。
对于没有父母的小组中的某个人来说,我没有遇到任何麻烦,但有些小组已经嵌套了2到3级。到目前为止,我尝试使用CTE方法尚未产生任何结果。
示例结果
Person.Name Membership.GroupID Group.GroupID Group.ParentGroupID Attribute.Value
Fred 3 1 NULL 'Attribute for Top level group'
Fred 3 2 1 'Attribute for a sub group'
Fred 3 3 2 'Attribute for third sub group'
Fred 5 4 1 'Attribute for Top level group - this is a duplicate?'
Fred 5 5 4 'Attribute for second sub group'
希望足够清楚。 Fred是Group 3的成员,其父组为2,而父组为3 - 然后显示每个组匹配的每个属性(Group.ID上的内部联接对Attribute.GroupID将实现此目的)
编辑 - 只需添加备注,每个人都可以是多个群组的成员。
答案 0 :(得分:2)
create table groups (groupid int, groupname varchar(10), parentgroupid int)
insert groups select 1, 'A', null;
insert groups select 2, 'B', null;
insert groups select 3, 'C', 1;
insert groups select 4, 'D', null;
insert groups select 5, 'E', null;
create table membership (personid int, groupid int);
insert membership select 1, 3;
insert membership select 1, 4;
create table person (personid int, name varchar(100));
insert person select 1, 'Jim';
create table Attribute(AttributeID int, GroupID int, Value varchar(100));
insert Attribute select 1, 1, 'At1-1';
insert Attribute select 2, 1, 'At1-2';
insert Attribute select 3, 2, 'At2-1';
insert Attribute select 4, 3, 'At3-1';
insert Attribute select 5, 4, 'At4-1';
;with tmp as (
select groupid membership_groupid, groupid
from membership
where personid = 1
union all
select membership_groupid, g.parentgroupid
from groups g
join tmp on tmp.groupid = g.groupid
)
select p.name, membership_groupid, g.groupid, g.parentgroupid, a.value
from person p
join tmp t on 1=1
join groups g on g.groupid = t.groupid
join attribute a on a.groupid = t.groupid
where p.personid = 1
如果一个人有可能成为GROUP A和GROUP A的父母的成员,你将需要打破平局以仅显示属性ONCE。
;with tmp as (
select groupid membership_groupid, groupid
from membership
where personid = 1
union all
select membership_groupid, g.parentgroupid
from groups g
join tmp on tmp.groupid = g.groupid
)
select p.name, membership_groupid, g.groupid, g.parentgroupid, a.value
from person p
join (select *, rn=row_number() over (partition by groupid
order by case when membership_groupid=groupid then 1
else 2 end,
membership_groupid)
from tmp) t on t.rn=1
join groups g on g.groupid = t.groupid
join attribute a on a.groupid = t.groupid
where p.personid = 1