我需要从规范化的人与人之间的关系数据中返回家庭群组。
存储人与人之间关系的数据采用以下结构(我无法更改),其中人与人之间的每个关系都以一对行表示,并标识每一方并使用FK到表中的相关行。
create table myRelationships (
id int
,PersonID int
,RelatedRowID int -- this is a FK to id for the related pair row
,RelationshipTypeID int -- not important for the purposes of this question
)
我可以在一行中明智地返回每个关系:
select
r1.PersonID as Person1ID
,r2.PersonID as Person2ID
,r1.RelationshipTypeID as P1toP2RelationshipType
from
myRelationships as r1
left join myRelationships as r2 on r1.RelatedRowID=r2.id
where
r1.PersonID<r2.PersonID -- so we don't get the same relationship in mirror-image as a 'duplicate'
我现在需要按照'家庭'对这些数据进行分组,其中所有人都是直接或n度相关的相关人员(例如与某人有关的人... )被分组到同一个桶中。以下是一些示例数据和预期结果。请注意,在这种情况下,关系类型并不重要 - 假设所有关系类型都表达符合我的家庭分组标准的家庭关系。
insert into myRelationships
values (1,1,2,1)
,(2,2,1,1)
,(3,1,4,1)
,(4,3,3,1)
,(5,4,6,1)
,(6,5,5,1)
,(7,1,8,1)
,(8,6,7,1)
,(9,7,10,1)
,(10,15,9,1)
,(11,8,12,1)
,(12,15,11,1)
期望的输出
FamilyGroup PersonID
1 1
1 2
1 3
1 6
2 4
2 5
3 7
3 8
3 15
答案 0 :(得分:3)
如何使用CTE执行此操作的示例:s。出于性能原因,您可能希望将一些CTE分解为带有索引的临时表。
编辑,第一个解决方案无效。这是一个新的尝试,在树的上下都有递归。因此,我需要跟踪我在“&#39;列表”中列出的内容。 (在此代码中只调用x的列)。通过这种方式,您可以找到每个人的最小相关ID,然后您可以对该最小ID进行分组。不确定这对大型数据集是否足够高效。
with ordered_relations as (
select r1.PersonID as id1, r2.PersonID as id2
from myRelationships r1
inner join myRelationships r2 on r2.id = r1.RelatedRowID
where r1.PersonID < r2.PersonID
)
, rec as (
select ',' + cast(r.id1 as varchar(max)) + ',' x, r.id1 as id, r.id1 as minid
from ordered_relations r
union all
select x + cast(r.id2 as varchar) + ',', r.id2, t.minid
from rec t
inner join ordered_relations r on r.id1 = t.id
and not t.x like '%,' + cast(r.id2 as varchar) + ',%'
union all
select x + cast(r.id1 as varchar) + ',', r.id1, case when r.id1 < t.minid then r.id1 else t.minid end
from rec t
inner join ordered_relations r on r.id2 = t.id
and not t.x like '%,' + cast(r.id1 as varchar) + ',%'
)
select dense_rank() over (order by min(minid)) groupid, id
from rec
group by id;
答案 1 :(得分:0)
我多年来一直在使用这样的层次结构,而且我不知道如何构建一个能够获得所需输出的SQL语句。树形结构,也称为树形结构,对计算机来说非常有意义,但在现实生活中使用起来很痛苦。这就是Microsoft创建hierarchyid数据类型的原因。
http://msdn.microsoft.com/en-us/library/bb677213(v=sql.110).aspx
由于您已经说过无法更改现有数据表,如果要返回从SQL格式化的数据,则需要创建一个可以处理递归逻辑并返回数据表结构的存储过程,或创建公用表表达式(CTE)。
http://technet.microsoft.com/en-us/library/ms186243%28v=sql.105%29.aspx
您所称的“家庭组”,MSFT链接中有关呼叫级别的示例。