【问题标题】:Find Parents Of Child in tree -Oracle在树中查找孩子的父母 -Oracle
【发布时间】:2021-08-22 19:44:48
【问题描述】:

我有这个示例表(作为分层 SQL 的树)。

我们如何根据孩子找到父母?

例如:查找“Sally”的父母 - 答案:Chris and Barbara Edsger and Barbara > Grandma

样本数据:

FAMILY_MEMBER MOTHER FATHER MARRIED_TO
Grandma null null Grandpa
Grandpa null null Grandma
Nana null null Granddad
Granddad null null Nana
Edsger Grandma Grandpa Grace
Ada Grandma Grandpa null
Grace Nana Granddad Edsger
Alan Nana Granddad null
Chris Grace Edsger Elizabeth
Barbara Grace Edsger null
Elizabeth null null Chris
Tim Elizabeth Chris null
Linus Elizabeth Chris null
Sally Elizabeth Chris null

我编写了这个查询来查找父母的孩子(并且它有效),但我无法编写查询来根据孩子查找父母。

SELECT lpad(' ',level*3,' ') || family_member as who, level
FROM family
start with family_member = 'Grandma'
Connect By Prior family_member IN (MOTHER, FATHER)

【问题讨论】:

  • 我无法理解规则:为什么芭芭拉是莎莉的父母,而伊丽莎白(被宣布为她的母亲)却不是?为什么 Edsger 也与 Barbara 配对,而树中只有一个 Barbara,是在上一步分配的?为什么格蕾丝也缺席了?您模型中的父母与我们在现实生活中所称的父母不同吗?
  • @astentx 莎莉的父母(伊丽莎白和克里斯),“埃兹格”有两个孩子:1-克里斯 2-芭芭拉,因为芭芭拉没有结婚也没有孩子,所以只重复了一次作为“Edsger”的孩子,而不是任何一行的父母
  • 例如:查找“Sally”的父母 - 答案:Chris 和 Barbara Edsger 和 Barbara > 奶奶

标签: sql oracle plsql


【解决方案1】:

只需反转条件:

SELECT lpad(' ',level*3,' ') || family_member as who,level
FROM family
START WITH family_member = 'Sally'
Connect By family_member IN (PRIOR mother, PRIOR father)

其中,对于您的示例数据:

CREATE TABLE family (FAMILY_MEMBER, MOTHER, FATHER, MARRIED_TO) AS
SELECT 'Grandma',   null,       null,       'Grandpa' FROM DUAL UNION ALL
SELECT 'Grandpa',   null,       null,       'Grandma' FROM DUAL UNION ALL
SELECT 'Nana',      null,       null,       'Granddad' FROM DUAL UNION ALL
SELECT 'Granddad',  null,       null,       'Nana' FROM DUAL UNION ALL
SELECT 'Edsger',    'Grandma',  'Grandpa',  'Grace' FROM DUAL UNION ALL
SELECT 'Ada',       'Grandma',  'Grandpa',  null FROM DUAL UNION ALL
SELECT 'Grace',     'Nana',     'Granddad',     'Edsger' FROM DUAL UNION ALL
SELECT 'Alan',      'Nana',     'Granddad',     null FROM DUAL UNION ALL
SELECT 'Chris',     'Grace',    'Edsger',   'Elizabeth' FROM DUAL UNION ALL
SELECT 'Barbara',   'Grace',    'Edsger',   null FROM DUAL UNION ALL
SELECT 'Elizabeth',     null,       null,       'Chris' FROM DUAL UNION ALL
SELECT 'Tim',       'Elizabeth',    'Chris',    null FROM DUAL UNION ALL
SELECT 'Linus',     'Elizabeth',    'Chris',    null FROM DUAL UNION ALL
SELECT 'Sally',     'Elizabeth',    'Chris',    null FROM DUAL;

输出:

WHO LEVEL
Sally 1
Chris 2
Edsger 3
Grandma 4
Grandpa 4
Grace 3
Nana 4
Granddad 4
Elizabeth 2

【讨论】:

    【解决方案2】:

    你找到Grandma,然后向下看树。尝试从 Sally 开始并查找树。

    select *
      from family
    connect by family_member = prior mother or family_member = prior father
    start with family_member = 'Sally'
    

    【讨论】:

    • 你写的查询是正确的,但是我分别尝试这两个用于**向下看** SELECT lpad(' ',level*3,' ') || family_member as who FROM family start with family_member = 'Grandma' Connect By Prior family_member IN (MOTHER,FATHER) 而这个用于向上看 SELECT lpad(' ',level*3,' ') || family_member as who,level FROM family START WITH family_member = 'Sally' Connect By family_member IN (PRIOR mother, PRIOR father)
    【解决方案3】:

    正如@MTO 所写,最终代码是这样的:

    --此查询显示 From Root 带有缩进的树

    SELECT lpad(' ',level*3,' ') || family_member as who
    FROM family
    start with family_member = 'Grandma'
    Connect By Prior family_member IN (MOTHER,FATHER)
    

    --此查询显示树从子级到根带有缩进

    SELECT lpad(' ',level*3,' ') || family_member as who,level
    FROM family
    START WITH family_member = 'Sally'
    Connect By family_member IN (PRIOR mother, PRIOR father)
    

    --如果你想工作更动态(带行号)

    select lpad(' ',level*3,' ') || name as NAMEE from z_tree
    start with id = 1
    Connect By Prior ID  =parent_id
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      相关资源
      最近更新 更多