一个BOM展开求总使用量问题求助:

当然也请各路高手拔刀相助

1.建表:

表1 结构表

create table

MANUF_STRUCTURE_TAB

(PART_NO  VARCHAR2(25) not null,

--父

COMPONENT_PART

VARCHAR2(25) not null,  --子

QTY_PER_ASSEMBLY

NUMBER not null)

--子对父的构成数(即1个父由多少个子构成)

表2 分类表

create table

INVENTORY_PART_TAB

(PART_NO  VARCHAR2(25) not null,  --编码

SK_PART_CATEGORY_DB  VARCHAR2(15) not null) --类别

2.说明:

表2中SK_PART_CATEGORY_DB分3类:

Product:成品

SemiProdudct:半成品

Component:原材料

3.想要结果:

1个成品所需要原材料的总使用量

PART_NO  COMPONENT_PART  T_QTY

......

测试数据及想要结果(想要结果未能列完)

想用sys_connect_by_path

把QTY_PER_ASSEMBLY用乘號串起來,

然後調用一個能執行動態SQL的function以得到結果.

简化一下你的数据:

create table

MANUF_STRUCTURE_TAB

(PART_NO  VARCHAR2(25) not

null,

COMPONENT_PART

VARCHAR2(25) not

null,

QTY_PER_ASSEMBLY

NUMBER not

null

);

create table

INVENTORY_PART_TAB

(PART_NO  VARCHAR2(25) not null,

SK_PART_CATEGORY_DB  VARCHAR2(15) not null

);

INSERT INTO

MANUF_STRUCTURE_TAB VALUES ('A1','B',2);

INSERT INTO

MANUF_STRUCTURE_TAB VALUES ('A2','B',3);

INSERT INTO

MANUF_STRUCTURE_TAB VALUES ('B','C',4);

INSERT INTO

MANUF_STRUCTURE_TAB VALUES ('C','D',7);

INSERT INTO

MANUF_STRUCTURE_TAB VALUES ('A1','C',6);

INSERT INTO

INVENTORY_PART_TAB VALUES ('A1','Product');

INSERT INTO

INVENTORY_PART_TAB VALUES ('A2','Product');

INSERT INTO

INVENTORY_PART_TAB VALUES ('B','SemiProdudct');

INSERT INTO

INVENTORY_PART_TAB VALUES ('C','Component');

INSERT INTO

INVENTORY_PART_TAB VALUES ('D','Component');

三种方法(既然你不喜欢自定义函数就没写了):

WITH t AS

(

SELECT

SYS_CONNECT_BY_PATH(a.part_no,'\')||'\'||a.component_part||'\' as

path

,qty_per_assembly

FROM

manuf_structure_tab a JOIN inventory_part_tab b

ON

a.part_no = b.part_no

START WITH

b.sk_part_category_db = 'Product'

CONNECT BY a.part_no = PRIOR

a.component_part

)

SELECT

root_part,part,SUM(qty) AS qty

FROM

(

SELECT

SUBSTR(t1.path,2,INSTR(t1.path,'\',1,2)-INSTR(t1.path,'\',1,1)-1)

as ROOT_PART

,SUBSTR(t1.path,INSTR(t1.path,'\',-1,2)+1,INSTR(t1.path,'\',-1,1)-INSTR(t1.path,'\',-1,2)-1)

as PART

,EXP(SUM(LN(t2.qty_per_assembly))) AS qty

FROM t

t1,t t2

WHERE t1.path LIKE

t2.path||'%'

GROUP BY

t1.path

)

GROUP BY

root_part,part;

WITH t AS

(

SELECT

SYS_CONNECT_BY_PATH(a.part_no,'\')||'\'||a.component_part||'\' as

path

,qty_per_assembly

FROM

manuf_structure_tab a JOIN inventory_part_tab b

ON

a.part_no = b.part_no

START WITH

b.sk_part_category_db = 'Product'

CONNECT BY a.part_no = PRIOR

a.component_part

)

SELECT

root_part,part,SUM(qty) AS qty

FROM

(

SELECT

SUBSTR(t1.path,2,INSTR(t1.path,'\',1,2)-INSTR(t1.path,'\',1,1)-1)

as ROOT_PART

,SUBSTR(t1.path,INSTR(t1.path,'\',-1,2)+1,INSTR(t1.path,'\',-1,1)-INSTR(t1.path,'\',-1,2)-1)

as PART

,(SELECT

EXP(SUM(LN(t2.qty_per_assembly))) FROM t t2 WHERE t1.path LIKE

t2.path||'%') AS qty

FROM t

t1

GROUP BY

t1.path

)

GROUP BY

root_part,part;

WITH t AS

(

SELECT

SYS_CONNECT_BY_PATH(a.part_no,'\')||'\'||a.component_part||'\' as

path

,SYS_CONNECT_BY_PATH(a.qty_per_assembly,'\')||'\' as

qty_path

,qty_per_assembly

FROM

manuf_structure_tab a JOIN inventory_part_tab b

ON

a.part_no = b.part_no

START WITH

b.sk_part_category_db = 'Product'

CONNECT BY a.part_no = PRIOR

a.component_part

)

SELECT

root_part,part,SUM(qty) AS qty

FROM

(

SELECT

SUBSTR(path,2,INSTR(path,'\',1,2)-INSTR(path,'\',1,1)-1) as

ROOT_PART

,SUBSTR(path,INSTR(path,'\',-1,2)+1,INSTR(path,'\',-1,1)-INSTR(path,'\',-1,2)-1)

as PART

,(SELECT

EXP(SUM(LN(SUBSTR(qty_path,INSTR(qty_path,'\',1,rn)+1,INSTR(qty_path,'\',1,rn+1)-INSTR(qty_path,'\',1,rn)-1))))

FROM (SELECT ROWNUM RN FROM DUAL CONNECT BY

ROWNUM<=100)

WHERE

SUBSTR(qty_path,INSTR(qty_path,'\',1,rn)+1,INSTR(qty_path,'\',1,rn+1)-INSTR(qty_path,'\',1,rn)-1)

IS NOT NULL

) AS

qty

FROM

t

)

GROUP BY

root_part,part;

如果最后只需要原材料,你自己过滤一下。

等会有空我用10G的MODEL来写一个。

用11GR2的递归WITH子查询应该是易如反掌,但我现在没环境测试。

---------------

发现有大量重复的,这是怎么回事?父、子应该构成唯一键。如果不唯一要先DISTINCT.

经测试第三种效果最好,和10G的MODEL差不多。

上面的方法都不新鲜了,这个10G的MODEL方法好像没见过:

WITH t AS

(

SELECT

SYS_CONNECT_BY_PATH(a.part_no,'\')||'\'||a.component_part as

path

,qty_per_assembly

,LEVEL

lvl

FROM

manuf_structure_tab a JOIN inventory_part_tab b

ON

a.part_no = b.part_no

START WITH

b.sk_part_category_db = 'Product'

CONNECT BY a.part_no = PRIOR

a.component_part

)

SELECT

root_part,part,SUM(qty) AS qty

FROM

(

SELECT

SUBSTR(path,2,INSTR(path,'\',1,2)-INSTR(path,'\',1,1)-1) as

ROOT_PART

,SUBSTR(path,INSTR(path,'\',-1,1)+1) as PART

,qty

FROM

t

MODEL IGNORE NAV RETURN

UPDATED ROWS

DIMENSION BY (path)

MEASURES (qty_per_assembly, 1

qty,lvl)

RULES AUTOMATIC ORDER

(

qty[any] order by path=(CASE

WHEN lvl[cv()]=1 THEN

qty_per_assembly[cv()]

ELSE qty_per_assembly[cv()]

*

qty[SUBSTR(cv(),1,INSTR(cv(),'\',-1,1)-1)]

END)

)

)

GROUP BY

root_part,part;

我的manuf_structure_tab有15万记录,INVENORY_PART_TAB有8W.

目前执行了5MIN还没反应.

WITH t AS

(

SELECT

SYS_CONNECT_BY_PATH(a.part_no,'\')||'\'||a.component_part||'\' as

path

,qty_per_assembly

FROM

manuf_structure_tab a,inventory_part_tab

b

where

a.part_no = b.part_no

and

a.contract=b.contract

and

b.contract='SKY'

START WITH

b.sk_part_category_db = 'Product'

CONNECT BY a.part_no = PRIOR

a.component_part

)

SELECT

root_part,part,SUM(qty) AS qty

FROM

(

SELECT

SUBSTR(t1.path,2,INSTR(t1.path,'\',1,2)-INSTR(t1.path,'\',1,1)-1)

as ROOT_PART

,SUBSTR(t1.path,INSTR(t1.path,'\',-1,2)+1,INSTR(t1.path,'\',-1,1)-INSTR(t1.path,'\',-1,2)-1)

as PART

,(SELECT

EXP(SUM(LN(t2.qty_per_assembly))) FROM t t2 WHERE t1.path LIKE

t2.path||'%') AS qty

FROM t

t1

GROUP BY

t1.path

)

GROUP BY

root_part,part

这样呢?

WITH t AS

(

SELECT

SYS_CONNECT_BY_PATH(a.part_no,'\')||'\' as path

,component_part as

part

,LEVEL

lvl

,SYS_CONNECT_BY_PATH(a.qty_per_assembly,'\')||'\' as

qty_path

FROM

manuf_structure_tab a JOIN inventory_part_tab b

ON

a.part_no = b.part_no

START WITH

b.sk_part_category_db = 'Product'

CONNECT BY a.part_no = PRIOR

a.component_part

)

SELECT

root_part,part,SUM(qty) AS qty

FROM

(

SELECT

SUBSTR(path,2,INSTR(path,'\',1,2)-2) as

ROOT_PART

,PART

,(SELECT

EXP(SUM(LN(SUBSTR(qty_path,INSTR(qty_path,'\',1,rn)+1,INSTR(qty_path,'\',1,rn+1)-INSTR(qty_path,'\',1,rn)-1))))

FROM (SELECT ROWNUM RN FROM DUAL CONNECT BY

ROWNUM<=100)

WHERE rn<=lvl

) AS

qty

FROM

t

)

GROUP BY

root_part,part;

---------------------------------------------------------------------------------------------------------------

| Id  |

Operation  | Name  | Rows  | Bytes |TempSpc| Cost

(%CPU)| Time  |

---------------------------------------------------------------------------------------------------------------

|  0 |

SELECT STATEMENT  |

|  804 |

3163K|  |  1216  (1)|

00:00:15 |

|  1 |

SORT AGGREGATE  |  |  1 |  13 |

|

|

|

|*  2 |

VIEW  |  |

1 |  13 |  |  2

(0)| 00:00:01 |

|  3 |

COUNT  |  |

|

|

|

|

|

|  4 |

CONNECT BY WITHOUT FILTERING|

|  |  |  |  |  |

|  5 |

FAST DUAL

|

|  1 |

|

|

2  (0)|

00:00:01 |

|  6 |

HASH GROUP BY  |  |

804 |  3163K|

13M|  1216

(1)| 00:00:15 |

|  7 |

VIEW  |  |

2587 |  9M|

|

9  (12)|

00:00:01 |

|*  8 |

CONNECT BY WITH FILTERING

|  |

|

|

|

|

|

|*  9 |

FILTER  |  |  |  |  |  |  |

|  10 |

COUNT

|  |

|

|

|

|

|

|* 11 |  HASH JOIN  |  |  2587 |

126K|  |  9

(12)| 00:00:01 |

|  12 |

TABLE ACCESS FULL  |

INVENTORY_PART_TAB  |  887 |

20401 |  |

3  (0)|

00:00:01 |

|  13 |

TABLE ACCESS FULL  |

MANUF_STRUCTURE_TAB |  2587 | 69849 |

|

5  (0)|

00:00:01 |

|* 14 |  HASH JOIN  |  |  |  |  |  |  |

|  15 |

CONNECT BY

PUMP  |

|  |  |  |  |  |

|  16 |

COUNT

|  |

|

|

|

|

|

|* 17 |  HASH JOIN  |  |  2587 |

126K|  |  9

(12)| 00:00:01 |

|  18 |

TABLE ACCESS FULL  |

INVENTORY_PART_TAB  |  887 |

20401 |  |

3  (0)|

00:00:01 |

|  19 |

TABLE ACCESS FULL  |

MANUF_STRUCTURE_TAB |  2587 | 69849 |

|

5  (0)|

00:00:01 |

|  20 |

COUNT  |  |  |  |  |  |  |

|* 21 |  HASH JOIN  |  |

2587 |  126K|

|

9  (12)|

00:00:01 |

|  22 |

TABLE

ACCESS FULL  | INVENTORY_PART_TAB

|  887 | 20401 |

|

3  (0)|

00:00:01 |

|  23 |

TABLE

ACCESS FULL  | MANUF_STRUCTURE_TAB |

2587 | 69849 |  |  5  (0)| 00:00:01

|

---------------------------------------------------------------------------------------------------------------

从你的数据量来看,遍历深度应该很浅啊?如果单独挑几种产品(在START

WITH中指定),速度怎么样?结果对吗?

单独把WITH里面的查询CREATE TABLE

AS...要花多少时间?生成的结果多大?这一步完成后尽量过滤(比如只保留你要的原料),让后面的乘法计算更少。

SELECT xmlquery('1*2*3*4'

returning content).getnumberval() FROM DUAL;

但是10G不支持变量,只能常量:

SELECT xmlquery(str returning

content).getnumberval()

FROM (SELECT '1*2*3*4' as str

FROM DUAL);

ERROR at line

1:

ORA-19102: XQuery string

literal expected

----

11GR2:

WITH t(root_part,part,qty) AS

(

SELECT a.part_no as

root_part, component_part as part,qty_per_assembly as

qty

FROM

manuf_structure_tab a JOIN inventory_part_tab b

ON

a.part_no = b.part_no

WHERE b.sk_part_category_db =

'Product'

UNION ALL

SELECT

a.root_part,b.component_part,a.qty*b.qty_per_assembly

FROM t a,

manuf_structure_tab b

WHERE a.part =

b.part_no

)

SELECT

root_part,part,SUM(qty) AS qty

FROM

t

GROUP BY

root_part,part;

ROOT_PART  PART  QTY

-------------------------

------------------------- ----------

A2  C  12

A1  D  98

A1  B  2

A2  B  3

A1  C  14

A2  D  84

oracle展bom逻辑,oracle 求BOM树型展开的总用量相关推荐

  1. 计算机的拓扑 树状结构图,树型网络拓扑结构

    树型网络拓扑结构[编辑] 树型网络拓扑结构简介:树型网络拓扑结构是网络节点呈树状排列,整体看来就象一棵朝上的树.树型网络拓扑结构是总线型结构的扩展,它是在总线网上加上分支形成的,其传输介质可有多条分支 ...

  2. oracle planning bom,OracleERP表结构--BOM模块

    BOM模块常用表结构 表名: bom.bom_bill_of_materials 说明: BOM清单父项目 BILL_SEQUENCE_ID NUMBER 清单序号(关键字) ASSEMBLY_ITE ...

  3. oracle的逻辑结构包括,oracle逻辑结构分析

    oracle数据库在逻辑上是由多个表间组成的,表空间中存储的对象叫段,比如数据段,索引段,和回退段.段由区组成,区是磁盘分配的最小单位.段的增大是通过增加区的个数来实现的.每个区的大小是数据块大小的整 ...

  4. oracle中更新一列分组的均值,oracle 分组平均后又求平均值的方法

    oracle 分组平均后再求平均值的方法 请教大家一个问题,是分组平均后再平均的方法 有一张表,记录物品的价格 名称   销售日期    价格 A     1日          2 A     2日 ...

  5. ORACLE表有逻辑坏块时EXPDP导出报错排查

    某用户反馈EXPDP导出脚本异常中断,接入排查后发现导出某表时报错,后台ALERT日志中也有相应报错:最终确认排查为逻辑坏块问题,经沟通得知为某个时间段的备份表,后续排除此表后重新设置EXPDP脚本, ...

  6. Oracle 物理读 逻辑读 一致性读 当前模式读总结浅析

    Oracle 物理读 逻辑读 一致性读 当前模式读总结浅析 在ORACLE数据库中有物理读(Physical Reads).逻辑读(Logical Reads).一致性读(Consistant Get ...

  7. mysql start with connect by_MYSQL实现Oracle的Start with…Connect By递归树查询

    最近接触一个老项目,最初适配的数据库是oracle 后来迁移到mysql .这个迁移是由一个已经离职的新手做的.这个新手对于很多oracle特有的函数及存储过程都没有进行迁移.导致系统很多功能都BUG ...

  8. ORACLE 树型层次结构查询

    为什么80%的码农都做不了架构师?>>>    ORACLE中的SELECT语句可以用 START WITH...CONNECT BY PRIOR 子句实现递归查询,CONNECT ...

  9. 数据导不进oracle数据库,学习笔记:Oracle逻辑导出/导入 数据逻辑导出时跳过指定表不进行导出...

    天萃荷净 Oracle数据库逻辑exp导出时,跳过指定某些表,对其表中数据不进行导出 有一个需求,某个用户有很多张表,但是只能使用exp导出,而且想跳过其中某几张表,其他对象包括依赖关系都需要.针对这 ...

最新文章

  1. 17 个品牌,113 款 5G 手机,5G 离我们越来越近
  2. c语言构造满二叉树,递归创建二叉树c语言实现+详细解释
  3. Linux下 运行Jmeter (含一个jmeter简单示例)
  4. 2020蓝桥杯省赛---java---A---2(既分数组)
  5. ViceDinoSpecCtrlDlg.cpp
  6. [转]notepad++各种插件
  7. eplan步进电机_干货丨三张接线图搞定步进电机接线问题!
  8. 【预训练模型】预训练语言模型的前世今生之风起云涌
  9. 数据结构常见算法机试题
  10. pytdx 获取板块指数_是否可以获得板块指数8806XX成分股?
  11. 开放微博社区使用OAUTH协议简介
  12. 计算机属性资源管理器已停止工作,windows资源管理器已停止工作,教您windows资源管理器已停止工作如何解决...
  13. UE4 UMG多行文本
  14. 智慧树期末考试可以切换页面吗_智慧树考试可以切换界面吗?中途可以退出吗...
  15. 第二章 马尔可夫决策过程及表格型方法
  16. WinCC 7.3 + SQL server(杂)
  17. 三国杀 中的概率计算 几何分布的期望和方差分析
  18. 微信公众号开发----生成带参数的临时二维码
  19. xp系统创建wifi连接服务器,xp笔记本连接无线wifi简便教程
  20. 作为学生借助 CODECHINA 这样学习 Git 知识

热门文章

  1. python--二叉树库函数
  2. linux suid 脚本,Linux使用suid vim.basic文件实现提权
  3. java rsa padding_rsa加密--选择padding模式需要注意的问题。。。
  4. 嵌入式系统功能需求分析_机械管理系统如何物料需求分析
  5. debug跳出循环_Java基础-第04章:循环结构「云图智联」
  6. C-Wandering Robot 模拟
  7. 教我兄弟学Android逆向
  8. Java实验4 面向对象基础
  9. P1181 数列分段Section I
  10. 算法优化——位运算的优化技巧