假设家人在下面:
此构建模式为:
create table PersonConn (child int, parent int)
insert into PersonConn values (1,2)
insert into PersonConn values (1,3)
insert into PersonConn values (5,3)
insert into PersonConn values (5,4)
insert into PersonConn values (6,7)
insert into PersonConn values (6,8)
insert into PersonConn values (2,9)
insert into PersonConn values (2,10)
insert into PersonConn values (3,11)
insert into PersonConn values (3,12)
为了获得家庭成员的祖先,我可以使用以下所示的递归:
WITH Childs AS (
SELECT distinct Child, Parent
FROM PersonConn
WHERE Child = 1
UNION ALL
SELECT t2.Child, t2.Parent
FROM [Childs] t1
INNER JOIN PersonConn t2
ON t2.Child = t1.parent
)
SELECT PARENT FROM CHILDS
将使用选定成员的所有祖先(在此示例中为ID 1),但不包括兄弟。该查询仅在家族树中上升。
我的[[问题是:
如何获得家庭的所有成员(儿子,父母,祖父,叔叔,堂兄等...)从一个人开始?
UPDATE
解决此问题的一种方法是在一个临时表中插入一个人的循环。之后,您可以将PersonConn
表与此临时表连接并插入其他人。这样做直到没有人插入为止。我正在寻找一种更有效(更优雅)的方法。 我在PersonConn
表中有大约200MM的记录。
hierarchyid
列。DECLARE @PersonId INT = 10
-- if id passed in is not a root child, then get one
If (SELECT Top 1 Parent FROM PersonConn WHERE Child = @PersonId) is null
WITH CHILDS AS (
SELECT Child, 0 as [level]
FROM PersonConn
WHERE Parent = @PersonId
UNION ALL
SELECT t2.Child, [level] + 1
FROM CHILDS t1
INNER JOIN PersonConn t2
ON t2.Parent = t1.Child
)
SELECT Top 1 @PersonId = Child FROM CHILDS ORDER BY [level] Desc;
WITH CHILDS AS (
SELECT Child, Parent
FROM PersonConn
WHERE Child = @PersonId
UNION ALL
SELECT t2.Child, t2.Parent
FROM CHILDS t1
INNER JOIN PersonConn t2
ON t2.Child = t1.parent
),
PARENTS AS (
SELECT Child, Parent
FROM PersonConn
WHERE Parent in (Select parent from CHILDS)
UNION ALL
SELECT t2.Child, t2.Parent
FROM PARENTS t1
INNER JOIN PersonConn t2
ON t2.parent = t1.child
),
CHILDS2 AS (
SELECT Child, Parent
FROM PersonConn
WHERE Child in(Select child From Parents)
UNION ALL
SELECT t2.Child, t2.Parent
FROM CHILDS2 t1
INNER JOIN PersonConn t2
ON t2.Child = t1.parent
)
SELECT DISTINCT Parent, Child FROM CHILDS2
表,我得到了很好的结果(但是我无法用2亿条记录对其进行测试)。如果使用临时表代替表变量,则可以索引PersonConn
,但我认为这样做不会提高性能,因为每次插入后都需要更新索引。