3

使用 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]
4

3 回答 3

2

我建议您使用 CTE(公用表表达式)查看递归。

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

于 2010-05-11T12:51:07.127 回答
2
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
于 2010-05-11T12:56:44.063 回答
0

这无法以现实的方式回答 - 暂时忽略 SQL 部分,但您甚至不知道自己想要什么。“也许”——好吧,再想一想。如果你有多个部分祖先怎么办?那你怎么办呢?

查找给定后代的所有祖先是微不足道的(临时表,递归填充它的父母,将“世代相距”添加为字段)。

然后你可以加入这两个临时表。到目前为止还不错(抱歉,基本上必须如此,因为您的层次结构可以追溯到很多代)。

但是从那里你仍然必须找到一个关于这应该意味着什么的真正合理的算法 - 在非平凡的场景中;)

于 2010-05-11T12:50:49.700 回答