得到家人

Niz*_*zam 7 sql sql-server sql-server-2012

以下家庭:

家谱

这个构建架构是:

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)
Run Code Online (Sandbox Code Playgroud)

为了获得一个家庭成员的祖先,我可以使用如下所示的递归:

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
Run Code Online (Sandbox Code Playgroud)

SQL小提琴

它将占用所选成员的所有祖先(在此示例中为ID 1),但不是例如兄弟.查询仅在族树中上升.

我的问题是:

如何让一个家庭的所有成员(儿子,父母,祖父,叔叔,表兄弟等......)从一个人开始?

UPDATE

解决此问题的一种方法是将人员插入临时表中.在您可以PersonConn使用此临时表连接表并插入其他人之后.这样做直到不再插入任何人.我正在寻找一种更有效(和优雅)的方式.我在PersonConn表中有大约200MM的记录.

Niz*_*zam 1

我找到的解决方案根本不好。它给出了正确的答案,但速度非常慢,即使对于这个非常小的表也是如此。

 DECLARE @INCLUIDOS TABLE (ID INT)

 INSERT INTO @INCLUIDOS VALUES(1)

 DECLARE @PAST_QUANT INT = 0
 DECLARE @QUANT INT = 1 

 WHILE @QUANT <> @PAST_QUANT
 BEGIN

     SET @PAST_QUANT = @QUANT

     INSERT INTO @INCLUIDOS
        SELECT PARENT 
        FROM PERSONCONN 
        WHERE CHILD IN (SELECT ID FROM @INCLUIDOS)
            AND PARENT NOT IN (SELECT ID FROM @INCLUIDOS)

    INSERT INTO @INCLUIDOS
        SELECT CHILD
        FROM PERSONCONN
        WHERE PARENT IN (SELECT ID FROM @INCLUIDOS)
            AND CHILD NOT IN (SELECT ID FROM @INCLUIDOS)

    SET @QUANT = (SELECT COUNT(*) FROM @INCLUIDOS)

END

SELECT DISTINCT ID FROM @INCLUIDOS
Run Code Online (Sandbox Code Playgroud)

SQL小提琴