Pregunta

Utilizando servidor SQL 2008.Tengo un árbol genealógico de animales almacenado en una tabla y quiero brindar información sobre cuán "genéticamente diversa" (o no) es la descendencia.En SQL, ¿cómo puedo producir métricas sensatas para mostrar qué tan estrechamente relacionados están los padres?¿Quizás algún tipo de porcentaje de sangre compartida, o varias generaciones antes de que haya un ancestro compartido?

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]
¿Fue útil?

Solución

Yo sugeriría nos fijamos en la recursividad utilizando un (expresión de tabla común) CTE.

Esto le permitirá a la mirada de forma recursiva a través de los padres hasta un ancestro común se encuentra manteniendo un valor para esto.

Otros consejos

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

Eso no se puede responder de manera realista: ignore la parte SQL por un momento, pero ni siquiera sabe lo que quiere."Quizás" - bueno, piénselo de nuevo.¿Qué pasa si tienes varios antepasados ​​parciales?¿Que haces entonces?

Encontrar todos los antepasados ​​de una descendencia determinada es trivial (tabla temporal, llénela con los padres de forma recursiva y agregue "generación de distancia" como campo).

Luego puedes unir las dos mesas temporales.Bien hasta ahora (y lo siento, básicamente tiene que serlo, porque su jerarquía puede remontarse a muchas generaciones atrás).

Pero a partir de ahí TODAVÍA tienes que encontrar un algoritmo sensato sobre lo que se supone que significa, en escenarios no triviales;)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top