简体   繁体   English

Sql 查询父子记录

[英]Sql query for parent child records

I need to find out final parent record for each child with a recursive logic until I find parent as null eg child=12 has final parent equal to 7. So as we traverse to find final parent all the non null values for L1, L2 and L3 will be populated in child record.我需要使用递归逻辑找出每个孩子的最终父记录,直到找到父记录为 null 例如 child=12 的最终父节点等于 7。因此,当我们遍历找到最终父节点时,L1、L2 和L3 将填充在子记录中。 May I get some guidance what SQL function I should use to generate following output.我可以得到一些指导,我应该使用什么 SQL function 来生成以下 output。

Input:输入:

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

Output: Output:

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

Create Table Statement:创建表语句:

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

populate data script:填充数据脚本:

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

I think you want to use the connect by to get the proper order.我认为您想使用 connect by 来获得正确的顺序。 You can get the last non null value by using the last value ignore nulls clause.您可以使用 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

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

You could also try below sql.您也可以在 sql 下方尝试。 It will work for many cases.它适用于许多情况。

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
;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM