【问题标题】:Sql query for parent child recordssql查询父子记录
【发布时间】:2021-03-02 22:57:04
【问题描述】:

我需要使用递归逻辑找出每个孩子的最终父记录,直到我找到父项为空,例如child=12 的最终父级等于 7 。 因此,当我们遍历找到最终父级时,L1、L2 和 L3 的所有非空值都将填充到子记录中。 我可以得到一些指导,我应该使用什么 SQL 函数来生成以下输出。

输入:

Child Parent  L1   L2   L3
12    435     xyz
435    7      xyz  abc  def
7     Null    xyz

输出:

 Child    L1   L2   L3
     7     xyz 
     435   xyz  abc  def
     12    xyz  abc  def

创建表语句:

CREATE TABLE mytable(
    child NUMBER,
    parent NUMBER,
    l1 varchar2(3),
    l2 varchar2(3),
    l3 varchar2(3)
);

填充数据脚本:

insert into mytable(child, parent, l1, l2, l3)
values (12, 435, 'xyz', null, null);
insert into mytable(child, parent, l1, l2, l3)
values (435, 7, 'xyz', 'abc', 'def');
insert into mytable(child, parent, l1, l2, l3)
values (7, null, 'xyz', null, null);

【问题讨论】:

    标签: sql oracle parent-child


    【解决方案1】:

    我认为您想使用 connect by 来获得正确的顺序。 您可以使用 last value ignore nulls 子句获取最后一个非 null 值。

      SELECT child, parent,
     last_value(l1) ignore nulls over (
               order by level rows between unbounded preceding and current row
             ) l1,
     last_value(l2) ignore nulls over (
               order by level rows between unbounded preceding and current row
             ) l2,
     last_value(l3) ignore nulls over (
               order by level rows between unbounded preceding and current row
             ) l3
          FROM mytable
          START WITH child = 7
          CONNECT BY PRIOR child = parent
    

    这是小提琴 http://sqlfiddle.com/#!4/b36736/10

    【讨论】:

      【解决方案2】:

      你也可以试试下面的sql。它适用于许多情况。

      with cte (CHILD, PARENT, L1, L2, L3,  temp_L1, temp_L2, temp_L3) as (
        select CHILD, PARENT, L1, L2, L3
              , L1 temp_L1, L2 temp_L2, L3 temp_L3
        from mytable
        where mytable.parent is null
        union all
        select t.CHILD, t.PARENT, t.L1, t.L2, t.L3
              , nvl2(t.L1, t.L1, c.temp_L1)temp_L1
              , nvl2(t.L2, t.L2, c.temp_L2)temp_L2
              , nvl2(t.L3, t.L3, c.temp_L3)temp_L3
        from mytable t 
        join cte c on t.parent = c.child
      )
      search depth first by child set order1
      select CHILD, /*PARENT,*/ temp_L1 L1, temp_L2 L2, temp_L3 L3
      from cte
      order by order1
      ;
      

      【讨论】:

      • 感谢您的回复,它正在工作,但最后一条记录 child=12 的级别为空。
      • 感谢您的评论。我对之前的答案进行了更新,以涵盖所有可能的情况。
      猜你喜欢
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      相关资源
      最近更新 更多