对同一表中的父子关系重新排序 - Oracle SQL



我在一个名为CPGRPRULREL的表中有以下数据。

CPGRPRULREL_NUM | CPGRPRULREL_NUM_PRIOR | STATUS     | CNDQUALSRC_CD | CNDQUALTYP_CD | CPGRP_NUM
--------------------------------------------------------------------------------------------------
41292           | 41289                 | Active     | PRODCNT       | PRODCNTUNQ    | 
41289           | 41286                 | Superseded | OTHERPG       |               | 118729
41286           | 41283                 | Superseded | SUBM          | VOLUME        | 
41283           | 41280                 | Superseded | OTHERPG       |               | 118729
41280           | 41277                 | Superseded | OTHERPG       |               | 118729
41277           | null                  | Superseded | PRODCNT       | PRODCNTALL    | 

在这里,CPGRPRULREL_NUM_PRIOR是指向CPGRPRULREL_NUM的链接(即具有外键约束 - 一种父子关系(。

我想删除所有CPGRP_NUM = 118729。在此之前,我需要更新其余行的 CPGRPRULREL_NUM_PRIOR 值,以便保持正确的链接不变。

我需要更新查询,它只会在运行更新后更新具有CPGRP_NUM <> 118729和以下数据的行。

CPGRPRULREL_NUM | CPGRPRULREL_NUM_PRIOR | STATUS     | CNDQUALSRC_CD | CNDQUALTYP_CD | CPGRP_NUM
--------------------------------------------------------------------------------------------------
41292           | 41286                 | Active     | PRODCNT       | PRODCNTUNQ    | 
41289           | 41286                 | Superseded | OTHERPG       |               | 118729
41286           | 41277                 | Superseded | SUBM          | VOLUME        | 
41283           | 41280                 | Superseded | OTHERPG       |               | 118729
41280           | 41277                 | Superseded | OTHERPG       |               | 118729
41277           | null                  | Superseded | PRODCNT       | PRODCNTALL    |            

请注意,CPGRPRULREL_NUM 41292 和 41286 的 2 行已CPGRPRULREL_NUM_PRIOR更新。

所以你想得到上一个CPGRPRULREL_NUM在哪里CPGRP_NUM <> 118729

这样的事情应该有效:

  • 构建树,从第一个开始(在先为空(
  • 如果前一个CPGRP_NUM118729,则:
    • 如果为 null,则返回上一个CPGRPRULREL_NUM_PRIORCPGRPRULREL_NUM

给:

with rws as (
select 41292 num, 41289 num_prior, null cpgrp_num from dual union all
select 41289 num, 41286 num_prior, 118729 from dual union all
select 41286 num, 41283 num_prior, null from dual union all
select 41283 num, 41280 num_prior, 118729 from dual union all
select 41280 num, 41277 num_prior, 118729 from dual union all
select 41277 num, null  num_prior, null from dual 
), tree ( num, num_prior, cpgrp_num ) as (
select * from rws
where  num_prior is null
union all
select r.num, 
case
when t.cpgrp_num = 118729 then nvl ( t.num_prior, t.num ) 
else r.num_prior
end num_prior, r.cpgrp_num 
from   rws r
join   tree t
on     t.num = r.num_prior
)
select * from tree;
NUM         NUM_PRIOR    CPGRP_NUM   
41277       <null>       <null> 
41280        41277       118729 
41283        41277       118729 
41286        41277       <null> 
41289        41286       118729 
41292        41286       <null>

使用分层子查询查找每个条目的叶值:

update cpgrprulrel c
set CPGRPRULREL_NUM_PRIOR =
(select CPGRPRULREL_NUM_PRIOR from cpgrprulrel
where connect_by_isleaf = 1
start with CPGRPRULREL_NUM = c.CPGRPRULREL_NUM_prior and cpgrp_num = 118729
connect by prior CPGRPRULREL_NUM_prior = CPGRPRULREL_NUM and cpgrp_num = 118729)
where cpgrp_num is null

德布提琴

然后,您可以删除不需要的行。

最新更新