Генеалогический запрос в Oracle - PullRequest
3 голосов
/ 23 апреля 2009

Я пытаюсь получить генеалогическое древо животных из моей базы данных Oracle.

Вот таблица:

Animal
------------------------
Animal_ID
Parent_Male_ID
Parent_Female_ID
....
....
------------------------

Если я укажу животное, я могу получить всех его потомков (с мужской стороны), используя что-то вроде этого:

SELECT *
FROM animal
START WITH animal_id = 123
CONNECT BY PRIOR animal_id = parent_male_id

Я пытаюсь найти способ расширить это так, что если я укажу животное, оно выберет обоих родителей, а затем выберет всех их потомков.

Есть мысли? (это Oracle 9.2)

1 Ответ

2 голосов
/ 23 апреля 2009
SELECT  *
FROM    animal
START WITH
        animal_id IN
        (
        SELECT  parent_male_id
        FROM    animal
        WHERE   animal_id = 123
        UNION ALL 
        SELECT  parent_female_id
        FROM    animal
        WHERE   animal_id = 123
        )
CONNECT BY
        PRIOR animal_id IN (parent_male_id, parent_female_id)

Этот запрос, однако, будет довольно медленным.

Лучше использовать это:

SELECT  DISTINCT(animal_id) AS animal_id
FROM    (
        SELECT  0 AS gender, animal_id, father AS parent
        FROM    animal
        UNION ALL
        SELECT  1, animal_id, mother
        FROM    animal
        )
START WITH
        animal_id IN
        (
        SELECT  father
        FROM    animal
        WHERE   animal_id = 9500
        UNION ALL 
        SELECT  mother
        FROM    animal
        WHERE   animal_id = 9500
        )
CONNECT BY
        parent = PRIOR animal_id
ORDER BY
        animal_id

, который будет использовать HASH JOIN и будет намного быстрее.

Смотрите эту запись в моем блоге для деталей производительности:

...