分层查询,帐户树

时间:2016-01-04 09:23:12

标签: sql oracle

我遇到了分层查询以搜索父母或子女帐户,通常我们假设一个例子:

表帐号:

Account    Parent
217518     217518 or null
304229     217518
424590     217518
378327     217518
491504     378327
234123     491504

所以层次结构看起来:

enter image description here

现在,我得到了表" SHOW_PARENT_CHILD_ACC"我将插入我想要显示的帐户。 (我需要在分层查询中使用它)

插入Show_parent_child_acc(acc)值(304229)。

查询应返回所有帐户ID,以便:

304229     
424590     
378327 
217518    
491504     
234123     

我愿意 插入show_parent_cild_acc(acc)值(234123)

查询应返回所有帐户ID,以便:

304229     
424590     
378327 
217518    
491504     
234123  

换句话说,无论哪个帐号(孩子的父/子或孩子)我都会插入show_parent_child_acc table.Query应该返回整个帐户层次结构

现在我有点像:

WITH acc_to_delete( ID ) AS (
                            select case when parentaccount is null then accountid else parentaccount end from account where accountid in                                          
                                 (select acc from show_parent_child_acc) 
                          )
                          SELECT accountid id_acc,case when parentaccount is null then accountid else parentaccount end parentaccount
                          FROM   account p
                          START WITH
                           EXISTS( SELECT 'X'
                                    FROM   acc_to_delete w
                                    WHERE  p.accountid = w.ID
                                    )
                          CONNECT BY accountid = PRIOR parentaccount
                          union
                          SELECT accountid id_acc,case when parentaccount is null then accountid else parentaccount end parentaccount
                          FROM   account p
                          START WITH
                          EXISTS( SELECT 'X'
                                    FROM   acc_to_delete w
                                    WHERE  p.accountid = w.ID
                                    )
                          CONNECT BY PRIOR accountid = parentaccount 

但它没有按预期工作(它在我放入SHOW_PARENT_CHILD_ACC:217518的情况下工作正常。)

2 个答案:

答案 0 :(得分:1)

我首先找到root id(子查询“root”),然后创建典型的层次结构:

with 
  tmp as (select acc from show_parent_child_acc ),
  root as (
    select max(acnt) keep (dense_rank last order by lvl) root
      from (
        select nvl(parentaccount, accountid) acnt, level lvl  
          from account a cross join tmp
          connect by nocycle prior parentaccount = accountid
          start with accountid = acc or parentaccount = acc ))
select accountid from account cross join root
  connect by nocycle prior accountid = parentaccount
  start with parentaccount = root.root
union select root from root

测试数据和输出:

create table account (accountid number(8), parentaccount number(8));
insert into account values (217518, 217518);
insert into account values (304229, 217518);
insert into account values (424590, 217518);
insert into account values (378327, 217518);
insert into account values (491504, 378327);
insert into account values (234123, 491504);
create table show_parent_child_acc (acc number(8));
insert into show_parent_child_acc values (234123);

AccountID
---------
   217518
   234123
   304229
   378327
   424590
   491504

答案 1 :(得分:1)

进一步修改原始查询,如下所示。

WITH acc_to_delete( ID ) AS (
                        select case when parentaccount is null then accountid else parentaccount end from account where accountid in                                          
                             (select acc from show_parent_child_acc) 
                      )                      
SELECT DISTINCT accountid id_acc, case when parentaccount is null then accountid else parentaccount end parentaccount 
FROM account START WITH parentaccount in
(                          
    SELECT case when parentaccount is null then accountid else parentaccount end parentaccount
    FROM   account p 
    START WITH
    EXISTS( SELECT 'X'
            FROM   acc_to_delete w
            WHERE  p.accountid = w.ID
        )
    CONNECT BY nocycle accountid = PRIOR parentaccount 
    UNION
    SELECT case when parentaccount is null then accountid else parentaccount end parentaccount
    FROM   account p 
    START WITH
    EXISTS( SELECT 'X'
            FROM   acc_to_delete w
            WHERE  p.accountid = w.ID
            )
    CONNECT BY nocycle PRIOR accountid =  parentaccount
) 
CONNECT BY NOCYCLE parentaccount = PRIOR accountid

主要是收集所有相应的父母,然后让他们的孩子。