2017-01-02 4 views
1

Я хочу создать представление, которое даст мне внуков самого старого человека, у которого есть некоторые. И проблема в том, что я не могу найти способ перевести в sql фразу: «у кого есть некоторые».Oracle SQL: генерации дерева деревьев с использованием деревьев

Я работаю только один стол, который является довольно простым:

лицо: номер (номер типа), имя, фамилия, DateOfBirth, пол, мать (номер типа), отец (номер типа).

Это то, что я пытался сделать:

Я попытался создать вид, который дает мне самый старый человек, который имеет grandchildrens (но это не то, что делается здесь)

CREATE OR REPLACE 
    VIEW oldestone 
    AS SELECT number FROM persons 
    WHERE (sysdate-dateofbirth)/365 >= ALL 
    (SELECT (sysdate-dateofbirth)/365 FROM persons) 
    AND EXISTS (SELECT * FROM persons 
        WHERE level=3 
      START WITH number = number 
      CONNECT BY PRIOR number = father OR PRIOR numero = mother); 

И номер первого взгляда я могу получить внуков:

CREATE OR REPLACE 
VIEW grandchildren 
AS SELECT firstname,lastname FROM persons 
    WHERE level=3 
    START WITH number = (SELECT number FROM oldestone) 
    CONNECT BY PRIOR number = father OR PRIOR number = mother; 

проблема в том, я знаю, что я не перевод: внуки старейшего человека у кого есть. Поскольку в моем первом представлении, когда я написал number = number, я хочу ссылаться на номер моей строки предложения select 3, но я знаю, что это не так.

Заранее благодарю вас за помощь ребятам!

Chris.

ответ

0

Если вы отмените направление, чтобы прочитать «вверх» генеалогическое древо, а не «вниз», вы можете перейти от внуков к своим родителям, а затем к бабушке и дедушке. По мере того, как вы это делаете, в самом внутреннем подзапросе вы можете «помнить» имена внуков с помощью оператора connect_by_root() и связывать их с датами рождения своих предков на разных уровнях (их собственные доки на уровне 1, уровень 2, их бабушки и дедушки на уровне 3).

В промежуточном подзапросе я выбираю строки, созданные иерархическим запросом на уровне 3, - который покажет даты рождения бабушек и дедушек. Я использую аналитическую функцию для записи минимальной даты рождения в том же запросе. (Вам не нужен «возраст» - «самый старый» означает самую раннюю дату рождения!)

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

Я создал некоторые очень простые тестовые данные в предложении WITH (не являющемся частью решения); вы можете протестировать более интересные материалы. Удачи!

with 
    person (id, last_name, first_name, dob, mother, father) as (
     select 1, 'Doe', 'John', date '1990-03-02', 2, 3 from dual union all 
     select 2, 'Doe', 'Anne', date '1962-11-21', 4, 5 from dual union all 
     select 3, 'Doe', 'Alan', date '1960-02-23', 6, 7 from dual union all 
     select 4, 'Orf', 'Jean', date '1953-10-11', 8, 9 from dual union all 
     select 5, 'Orf', 'Stan', date '1952-09-06', 10, 11 from dual union all 
     select 22, 'Sun', 'Ryan', date '1968-02-21', 23, 24 from dual union all 
     select 23, 'Sun', 'Mary', date '1934-12-09', 26, 27 from dual 
    ) 
-- end of test data; solution (SQL query) begins below this line 
select last_name, first_name 
from (
     select last_name, first_name, dob, min(dob) over() as min_dob 
     from (
        select connect_by_root(last_name) as last_name , 
         connect_by_root(first_name) as first_name, dob, level as lvl 
        from person 
        connect by id in (prior mother, prior father) 
     ) 
     where lvl = 3 
) 
where dob = min_dob 
; 

LAST_NAME FIRST_NAME 
--------- ---------- 
Doe  John 
Смежные вопросы