Вопрос

Используя 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]
Это было полезно?

Решение

Я бы предложил вам посмотреть на рекурсию, используя CTE (распространенное выражение таблицы).

Это позволит вам рекурсивно просматривать родителей до тех пор, пока не будет найден общего предка, одновременно поддерживая ценность для этого.

Другие советы

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

Это нельзя ответить в реалистичном беде - игнорируйте часть SQL на мгновение, но вы даже не знаете, что вы хотите. «Возможно» - ну, подумайте это снова. Что делать, если у вас есть несколько частичных предков? Что вы делаете тогда?

Нахождение всех предков данного потомства является тривиальным (TEMP Table, заполнить его родителями рекурсивно, добавляя «поколение» в качестве поля).

Тогда вы можете присоединиться к двум временным таблицам. Хорошо до сих пор (и извините, что в основном должно быть, потому что ваша иерархий может поколебать еще много поколений).

Но оттуда вы все еще должны найти на самом деле разумный алгоритм на то, что предполагается означать - в нетривиальных сценариях;)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top