Oracle SQL:使用树的族树视图

时间:2017-01-02 17:50:47

标签: oracle tree family-tree

我想创建一个视图,他给了我最年长的人的孙子孙女。 问题是我找不到在sql中翻译的方法:"谁有一些"。

我只在一张非常基本的表中工作:

人:号码(型号),姓氏,名字,日期,性别,母亲(型号),父亲(型号)。

这就是我试图做的事情:

我试图创建一个视图,它给了我最年长的有孙子的人(但这不是在这里做的)

new Date().valueOf()

根据第一个视图的数量,我可以得到孙子:

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

问题是我知道我没有翻译:最年长的人的孙子谁有一些。因为在我的第一个视图中,当我写了number = number时,我想引用我的select子句第3行的编号,但我知道情况并非如此。

先谢谢你们帮帮忙!

克里斯。

1 个答案:

答案 0 :(得分:0)

如果您反转方向,请阅读" up"家谱,而不是" down",你可以从孙子孙女到父母,再到祖父母。当你这样做时,在最里面的子查询中,你可以记住"孙子的名字与connect_by_root()运营商联系,并将他们与不同级别的祖先的出生日期联系起来(他们自己在1级的dob,他们的父母' dob&#39 ;在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