递归SQL计算-无法执行递归计算

时间:2019-04-12 15:31:58

标签: sql oracle recursion oracle12c

我正在研究一个Oracle数据库实例,试图计算递归物料清单。

我的数据集如下所示(我确实不需要其他功能)

| Root_Part_No | Sub_Part_No | Sub_Part_Quant |
|--------------|-------------|----------------|
| 132EER       | 122FYY      | 4              |
| 132EER       | 766WWW      | 2              |
| 132EER       | 001EWW      | 1              |
| 132EER       | 472WQA      | 1              |
| 132EER       | 632OIR      | 1              |
| 132EER       | 874RTG      | 1              |
| 132EER       | 888III      | 10             |
| 132EER       | 235CVV      | 5              |

我可以使用以下查询很好地计算一级BOM:

SELECT 
    Root_Part_No, 
    TRIM(Sub_Part_No) AS "Part", 
    Sub_Part_Qty

FROM 
    TblBOM 

WHERE
    Root_Part_No LIKE "132EE%" 
    AND isEmptyInd != 'Yes'

ORDER BY Root_Part_No, Sub_Part_Qty;

但是,我需要要完成的工作是能够为我输入的项目返回的每个Sub_Part_No计算BOM的能力,最终得到一个看起来像喜欢:

| Root_Part_No | Sub_Part_No | Sub_Part_Quant |
|--------------|-------------|----------------|
| 132EER       | 122FYY      | 4              |
| 132EER       | 766WWW      | 2              |
| 132EER       | 001EWW      | 1              |
| 132EER       | 472WQA      | 1              |
| 132EER       | 632OIR      | 1              |
| 132EER       | 874RTG      | 1              |
| 132EER       | 888III      | 10             |
| 132EER       | 235CVV      | 5              |
| 122FYY       | 849ZXA      | 2              |
| 122FYY       | 990JUI      | 10             |
| 122FYY       | 211EEW      | 5              |
| 122FYY       | 211VVV      | 2              |
| 766WWW       | 001EWW      | 10             |
| 766WWW       | 176LKJ      | 2              |
...etc

我尝试了以下两种资源:

我对join第二部分的UNION部分感到困惑。 感谢您在前进的道路上提供任何帮助。

使用RPL AS(     SELECT Root_Part_No,TRIM(Sub_Part_No)AS“ Part”,Sub_Part_Qty     来自TblBOM
    Root_Part_No类似于“ 132EE%”且isEmptyInd!='是'

UNION ALL

SELECT Root_Part_No, TRIM(Sub_Part_No) AS "Part", Sub_Part_Qty
FROM TblBOM
LEFT JOIN -- I am confusion

    )

  SELECT DISTINCT -- I am also confusion

1 个答案:

答案 0 :(得分:2)

一个简单的递归查询即可获得所需的内容:

with
i (root_part_no, sub_part_no, sub_part_quant, lvl) as (
  select 
    root_part_no, sub_part_no, sub_part_quant, 1
  from tblbom where root_part_no like '132EE%' and isemptyind <> 'Yes'
  union all -- anchor member above; recursive member below
  select
    p.root_part_no, p.sub_part_no, p.sub_part_quant, i.lvl + 1
  from i
  join tblbom p on p.root_part_no = i.sub_part_no
)
select * 
from i
order by lvl, root_part_no, sub_part_no

请注意UNION ALL子句。它将锚查询(仅运行一次)与递归查询分开,该查询针对由此产生的每个新行运行多次,直到不再产生新行。这样,此查询可以遍历多个级别,而不仅仅是两个。

修改

我使用以下(组合)数据测试了上面的查询,并添加了LVL列以显示递归级别:

create table tblbom (
  root_part_no varchar2(10),
  sub_part_no varchar2(10),
  sub_part_quant number(6),
  isemptyind varchar2(10) default 'No'
);

insert into tblbom (root_part_no, sub_part_no, sub_part_quant) values ('132EER', '122FYY', 1);
insert into tblbom (root_part_no, sub_part_no, sub_part_quant) values ('132EER', '766WWW', 2);
insert into tblbom (root_part_no, sub_part_no, sub_part_quant) values ('122FYY', '849ZXA', 3);
insert into tblbom (root_part_no, sub_part_no, sub_part_quant) values ('766WWW', '111111', 4);
insert into tblbom (root_part_no, sub_part_no, sub_part_quant) values ('849ZXA', null, 5);
insert into tblbom (root_part_no, sub_part_no, sub_part_quant) values ('111111', null, 6);

结果(包括级别)为:

ROOT_PART_NO  SUB_PART_NO  SUB_PART_QUANT  LVL
------------  -----------  --------------  ---
132EER        122FYY       1               1  
132EER        766WWW       2               1  
122FYY        849ZXA       3               2  
766WWW        111111       4               2  
111111        <null>       6               3  
849ZXA        <null>       5               3