2017-01-02 4 views
1

私に最も古い人の孫を与えるビューを作成したいと考えています。 問題は、SQLで "who have some"というフレーズを翻訳する方法が見つからないということです。Oracle SQL:ツリーを使用したファミリ・ツリー・ビュー

私はかなり基本的なものだけで一つのテーブルで作業:

者:番号(型番)、姓、ファーストネーム、dateOfBirthの、性別、母(型番)、父(型番)。

これは私が何をしようとしたものです:

私は

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); 

としてくれgrandchildrensを持っている(これはここで行われているものではありません)最古の人物を与えるビューを作成しようとしました私は孫を得ることができ、最初のビューの数:

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の自分のdob、親のdob'sレベル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 
関連する問題