在家谱树上的SQL循环

时间:2010-05-11 12:46:19

标签: sql tsql family-tree

使用SQL Server 2008。 我有一个存放在桌子上的动物家谱,想要提供一些关于后代是如何“遗传多样化”的信息。 在SQL中,我如何生成合理的指标来显示父母的亲密关系? 也许是某种百分比的共享血液,或者在有共同祖先之前回归的几代人?

AnimalTable 
Id
Name
mumId
dadId

select * from AnimalTable child
inner join AnimalTable mum on child.[mumId] = mum.[Id]
inner join AnimalTable dad on child.[dadId] = dad.[Id]

inner join AnimalTable mums_mum on mum.[mumId] = mums_mum.[Id]
inner join AnimalTable mums_dad on mum.[dadId] = mums_dad.[Id]

inner join AnimalTable dads_mum on dad.[mumId] = dads_mum.[Id]
inner join AnimalTable dads_dad on dad.[dadId] = dads_dad.[Id]

3 个答案:

答案 0 :(得分:2)

我建议你使用CTE(Common Table Expression)查看递归。

这将允许您递归查看父母,直到找到共同的祖先,同时保持此值。

答案 1 :(得分:1)

WITH    hier1(parent, level) AS
        (
        SELECT  mum, 1
        FROM    AnimalTable a
        WHERE   a.id = @first_animal
        UNION ALL
        SELECT  dad, 1
        FROM    AnimalTable a
        WHERE   a.id = @first_animal
        UNION ALL
        SELECT  mum, level + 1
        FROM    q
        JOIN    AnimalTable a
        ON      a.id = q.parent
        UNION ALL
        SELECT  dad, level + 1
        FROM    q
        JOIN    AnimalTable a
        ON      a.id = q.parent
        ),
        hier2(parent, level) AS
        (
        SELECT  mum, level
        FROM    AnimalTable a
        WHERE   a.id = @second_animal
        UNION ALL
        SELECT  dad, level
        FROM    AnimalTable a
        WHERE   a.id = @second_animal
        UNION ALL
        SELECT  mum, level + 1
        FROM    q
        JOIN    AnimalTable a
        ON      a.id = q.parent
        UNION ALL
        SELECT  dad, level + 1
        FROM    q
        JOIN    AnimalTable a
        ON      a.id = q.parent
        )
SELECT  TOP 1
        h1.parent,
        CASE WHEN h1.level < h2.level THEN h1.level ELSE h2.level END AS minlevel
FROM    hier1 h1
JOIN    hier2 h2
ON      h1.parent = h2.parent
ORDER BY
        2

答案 2 :(得分:0)

在现实的时尚中无法回答 - 暂时忽略SQL部分,但你甚至不知道自己想要什么。 “也许” - 好吧,再考虑一遍。如果您有多个部分祖先怎么办?那你做什么?

查找给定后代的所有祖先是微不足道的(临时表,递归地填充父母的内容,将“生成之外”添加为字段)。

然后你可以加入两个临时表。好到目前为止(对不起,基本上必须这样,因为你的等级可以回到很多代)。

但是从那里开始你仍然必须找到一个合理的算法来解决这个问题 - 在非平凡的场景中;)