【问题标题】:Recursive SQL Calculation - Recursive Calculation Cannot Be Performed递归 SQL 计算 - 无法执行递归计算
【发布时间】:2019-09-03 10:05:37
【问题描述】:

我正在处理一个试图计算递归物料清单的 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

我尝试了以下两种资源:

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

使用 RPL 作为 ( 选择 Root_Part_No,TRIM(Sub_Part_No)作为“零件”,Sub_Part_Qty 来自 TblBOM
WHERE Root_Part_No LIKE "132EE%" AND isEmptyInd != 'Yes'

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

【问题讨论】:

  • 您使用的是什么版本的 Oracle?
  • 我的驱动程序是 12c,所以我不确定这是否有帮助。我说不出来。如果有帮助,我正在使用 SQL Developer 查询实例。
  • 如果一个部件需要 x2 子部件,那么该子部件需要 x3,那么……它仍然是 x3 子部件,还是 x6?
  • 我想“数量”是指构建当前在Root_Part_No 列出的部件所需的数量。从本质上讲,我认为这是使用我对来自该查询的第一个实例的每个部件号的单级查询的问题。我知道这是递归,但我不知道该怎么做。
  • 您是否需要此查询一直递归到所需的基本部分,还是只需要您列出的示例中的那个级别?我问是因为使用示例中的查询找到的部分也可能有子部分。

标签: sql oracle recursion oracle12c


【解决方案1】:

得到你想要的东西的简单递归查询是:

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 子句。它将 锚定查询(只运行一次)与 递归查询 分开,该查询对每个 新行 产生的每个 新行 运行多次,直到它不再产生新行。这样,此查询可以遍历多个级别,而不仅仅是其中的 2 个。

编辑

我使用以下(组成)数据测试了上面的查询,并添加了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  

【讨论】:

  • 嘿@TheImpaler,非常感谢您的回答。所以,也许我没有以正确的方式表达我的问题。这绝对有效,但它似乎只拉第一级。意思是,我只是尝试运行它,它正在提取所有 FIRST 级材料,与我的类似,但它并没有为那些产生的零件编号提取 BOM。所以有些事情不对:(
  • 我相信您可以通过使用UNION 而不是UNION ALL 来拉动以下所有级别。 UNION ALL 删除了重复项,因此您只会看到第一个。这也可能导致递归问题,因此如果查询开始运行时间过长,请准备好终止查询。
  • 删除UNION ALL 语法导致ORA-32040: recursive WITH clause must use a UNION ALL operation
  • @drakin8564 您无法删除UNION ALL。 Oracle 要求它们处理递归查询。
  • 这不起作用,因为我的 TRIM 错误。你是对的。非常感谢,这太棒了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多