3

SQL サーバー 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
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 に答える
2

CTE (Common Table Expression) を使用した再帰を検討することをお勧めします。

これにより、値を維持しながら、共通の祖先が見つかるまで親を再帰的に調べることができます。

于 2010-05-11T12:51:07.127 に答える
0

それは現実的な形で答えることはできません - SQL の部分をしばらく無視してください。「たぶん」 - よく考えてみてください。部分的な先祖が複数いる場合はどうなりますか? だったらどうしようか?

特定の子孫のすべての祖先を見つけるのは簡単です (一時テーブルに親の値を再帰的に入力し、フィールドとして「離れた世代」を追加します)。

次に、2 つの一時テーブルを結合できます。ここまでは良かったです (そして申し訳ありませんが、階層は何世代にもわたって遡ることができるため、基本的にそうする必要があります)。

しかし、そこから、それが何を意味するのかについて実際に賢明なアルゴリズムを見つける必要があります-自明ではないシナリオで;)

于 2010-05-11T12:50:49.700 に答える