展开BOM并使用最终用量的算法(转载)
本文系转载子ITPUB,如果有侵犯您权益的地方,烦请及时的告知与我,我即刻将停止侵权行为:
网址:http://www.itpub.net/thread-1020586-1-1.html
http://www.itpub.net/thread-1020772-3-1.html
http://www.itpub.net/thread-1020712-1-1.html
LEVEL Parent Child Parent Qty Child Qty
1 A B 1 3
2 B C 2 3
3 C D 5 6
4 D E 1 2
1 A Z 1 3
A是成品
B,C,D是半成品
E,Z是原材料
从上面一个比例关系可以计算出,做一个A最终需要10.8个E和3个Z,
也就是能看到下面的结果
Parent Child QTY
A E 10.8
A Z 3
我想知道有没有什么办法通过一个SQL语句来实现这个功能。
测试表:
CREATE TABLE BOM (PARENT VARCHAR2(10),CHILD VARCHAR2(10),P_QTY NUMBER, C_QTY NUMBER);
INSERT INTO BOM VALUES ('A','B',1,3);
INSERT INTO BOM VALUES ('B','C',2,3);
INSERT INTO BOM VALUES ('C','D',5,6);
INSERT INTO BOM VALUES ('D','E',1,2);
INSERT INTO BOM VALUES ('A','Z',1,3);
COMMIT;
1、使用SQL
SELECT P, D, SUM(QTY)
FROM (SELECT P, C, D, POWER(10, SUM(LOG(10, QTY))) AS QTY
FROM (SELECT DISTINCT P,
C,
SUBSTR(C, -1, 1) D,
REGEXP_SUBSTR(C, '[^,]+', 1, LEVEL),
TO_NUMBER(REGEXP_SUBSTR(Q, '[^*]+', 1, LEVEL)) AS QTY
FROM (SELECT CONNECT_BY_ROOT PARENT AS P,
SUBSTR(SYS_CONNECT_BY_PATH(CHILD, ','), 2) AS C,
1 || SYS_CONNECT_BY_PATH(C_QTY / P_QTY, '*') AS Q
FROM BOM
WHERE CONNECT_BY_ISLEAF = 1
START WITH PARENT = 'A'
CONNECT BY PARENT = PRIOR CHILD) C
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(Q, '[^*]', '')) + 1
ORDER BY 1, 2) TT
GROUP BY P, C, D) FF
GROUP BY P, D
2、使用NEWID提供的聚合求积函数
解决思路:
1.把A的每个叶子找出来;
2.顺着叶子往根,一路作乘法上去。
SELECT CHILD,
(SELECT PROD_AGG(C_QTY) / PROD_AGG(P_QTY)
FROM BOM
CONNECT BY PRIOR PARENT = CHILD
START WITH CHILD = INNER.CHILD -- 从每个叶子开始
) AS C_QTY
FROM (SELECT BOM.*, CONNECT_BY_ISLEAF AS IS_LEAF
FROM BOM
CONNECT BY PRIOR CHILD = PARENT
START WITH PARENT = 'A')
INNER WHERE IS_LEAF = 1 -- 这个条件找出所有的叶子
其中PROD_AGG 见:
http://www.itpub.net/thread-1020772-1-1.html
CHILD C_QTY
---------- ----------
E 10,8
Z 3
不用PRO_AGG的方法:
不用 PROD_AGG的办法:
SELECT CHILD
,(SELECT POWER(10,SUM(LOG(10,C_QTY)))/POWER(10,SUM(LOG(10,P_QTY)))
FROM BOM
CONNECT BY PRIOR PARENT=CHILD
START WITH CHILD = inner.CHILD -- 从每个叶子开始
) AS C_QTY
FROM (SELECT BOM.*
,CONNECT_BY_ISLEAF AS IS_LEAF
FROM BOM
CONNECT BY PRIOR CHILD = PARENT
START WITH PARENT='A'
) inner
WHERE IS_LEAF=1; -- 这个条件找出所有的叶子
3、使用PL/SQL的方法:可以将1替换为connect_by_isleaf:如果为叶子节点,则该函数的值1,否则为0,刚好可以替代1,
SELECT CHILD, GET_EXPRESSION_RSLT(CON_QTY)
FROM (SELECT CHILD,
LEVEL M,
1 || SYS_CONNECT_BY_PATH(C_QTY / P_QTY, '*') CON_QTY
FROM BOM
WHERE CONNECT_BY_ISLEAF = 1
START WITH PARENT = 'A'
CONNECT BY PARENT = PRIOR CHILD) A
结果:
1 E 10.8
2 F 3.85714285714285714285714285714285714287
3 Z 3
自定义函数:
CREATE OR REPLACE FUNCTION GET_EXPRESSION_RSLT(I_EXPRESSION VARCHAR2) RETURN VARCHAR2 IS
/************************************************************
* 函数名称:GET_EXPRESSION_RSLT
* 功能描述:获取指定的表达式的结果
* 参数:I_EXPRESSION :表达式 例如:1*2*3
* 编 写 人:XXX
* 编写时间:XXXX-XX-XX
* 修改记录:
*************************************************************/
RETURNSTR VARCHAR2(500) := '';
EXECSQL VARCHAR2(4000) := '';
BEGIN
EXECSQL := ' SELECT ' || I_EXPRESSION || ' FROM DUAL';
EXECUTE IMMEDIATE (EXECSQL)
INTO RETURNSTR;
RETURN RETURNSTR;
END;
如果要看A用了每个B,C,D,E
则只需要将CONNECT_BY_SILEFT=1去掉即可
也可以使用下面的语句:
SELECT CHILD, dbms_aw.eval_number(CON_QTY)
FROM (SELECT CHILD,
LEVEL M,
1 || SYS_CONNECT_BY_PATH(C_QTY / P_QTY, '*') CON_QTY
FROM BOM
WHERE CONNECT_BY_ISLEAF = 1
START WITH PARENT = 'A'
CONNECT BY PARENT = PRIOR CHILD) A
其中dbms_aw.eval_number这个函数是用来解析字符串函数的
或者使用with函数
WITH H AS
(SELECT SYS_CONNECT_BY_PATH(CHILD, '/') NAVPATH,
CHILD,
QUANTITY QTY,
ISLEAF
FROM ITEMHIER
START WITH PARENT = 'ASSY001'
CONNECT BY PRIOR CHILD = PARENT)
SELECT H1.NAVPATH, H1.CHILD,(
SELECT /*EXP(SUM(LN(H2.QTY))),*/
POWER(10, SUM(LOG(10, QTY)))
FROM H H2
WHERE INSTR(H1.NAVPATH, H2.NAVPATH) = 1) QTY
FROM H H1
WHERE ISLEAF = 1
展开BOM并使用最终用量的算法(转载)的更多相关文章
- Facebook开源时间序列内存数据库Beringei,追求极致压缩率——如果是int根据大多数时间序列中的值与相邻数据点相比并没有显著的变化,只要使用XOR将当前值与先前值进行比较,然后存储发生变化的比特。最终,该算法将整个数据集至少压缩了90%
转自:http://www.infoq.com/cn/news/2017/02/Facebook-Beringei 2017年2月3日,Facebook宣布将开源他们的高性能时序数据存储引擎Berin ...
- A* 寻路算法[转载]
A* 寻路算法 转载地址:http://www.cppblog.com/christanxw/archive/2006/04/07/5126.html 原文地址: http://www.gamedev ...
- AStar算法(转载)
以下的文章来至http://blog.csdn.net/debugconsole/article/details/8165530,感激这位博主的翻译,可惜图片被和谐了,所以为方便阅读,我重新把图片贴上 ...
- 调用sklearn包中的PLA算法[转载]
转自:https://blog.csdn.net/u010626937/article/details/72896144#commentBox 1.Python的机器学习包sklearn中也包含了感知 ...
- Rsync实现文件同步的算法(转载)
Rsync文件同步的核心算法 文章出处:http://coolshell.cn/articles/7425.html#more-7425 rsync是unix/linux下同步文件的一个高效算法,它能 ...
- 数据结构图之三(最短路径--迪杰斯特拉算法——转载自i=i++
数据结构图之三(最短路径--迪杰斯特拉算法) [1]最短路径 最短路径?别乱想哈,其实就是字面意思,一个带边值的图中从某一个顶点到另外一个顶点的最短路径. 官方定义:对于内网图而言,最短路径是指两 ...
- FP-Tree -关联规则挖掘算法(转载)
在关联规则挖掘领域最经典的算法法是Apriori,其致命的缺点是需要多次扫描事务数据库.于是人们提出了各种裁剪(prune)数据集的方法以减少I/O开支 支持度和置信度 严格地说Apriori和FP- ...
- GJM : 数据结构 - 轻松看懂机器学习十大常用算法 [转载]
转载请联系原文作者 需要获得授权,非法转载 原文作者将享受侵权诉讼 文/不会停的蜗牛(简书作者)原文链接:http://www.jianshu.com/p/55a67c12d3e9 通过本篇文章可以 ...
- 浅谈MySQL索引背后的数据结构及算法(转载)
转自:http://blogread.cn/it/article/4088?f=wb1 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储 ...
随机推荐
- LOL是什么意思? - 已解决 - 搜狗问问
LOL是什么意思? - 已解决 - 搜狗问问 N A T S U . |分类:QQ工具栏 2009-05-04 LOL是什么意思? 满意答案 Shim Nyong 19级 2009-05-04 LOL ...
- 传纸条(一)(双线程dp)
传纸条(一) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行 ...
- ORA-02287: 此处不同意序号
ORA-02287: 此处不同意序号 insert into gls_vchitem (viid, yr, km) select gls_vchitem_seq.n ...
- 关于ql createNativeQuery生成json数据
当用createNativeQuery执行原生sql语句时,返回的数据json格式是只有值,没有键名的,在这种情况下要用Map.class对sql语句中的字段进行Map映射,这样返回的数据的json格 ...
- Flink资料(6) -- 如何添加一个新的Operator
false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-n ...
- codeforces 665D Simple Subset
题目链接 给一个数列, 让你选出其中的m个数, 使得选出的数中任意两个数之和都为质数, m尽可能的大. 首先, 除了1以外的任意两个相同的数相加结果都不是质数. 然后, 不考虑1的话, 选出的数的个数 ...
- FAQ:注册表_键值类型
在注册表中,“键值项数据”可分为下面三种类型. 字符串值(REG_SZ) 该值一般用来作为文件描述和硬件标志,可以是字母.数字,也可以是汉字,但它是长度固定的文本字符串,最大长度不能超过255个字符. ...
- Oracle GoldenGate学习之Goldengate介绍
Oracle GoldenGate学习之Goldengate介绍 (2012-10-02 17:07:27) 标签: 检查点 数据传输 队列 进程 分类: Goldengate Goldengate介 ...
- CF卡是什么
CF卡(Compact Flash)最初是一种用于便携式电子设备的数据存储设备.作为一种存储设备,它革命性的使用了闪存,于1994年首次由SanDisk公司生产并制定了相关规范.当前,它的物理格式已经 ...
- SymPy-符号运算好帮手
SymPy-符号运算好帮手 SymPy是Python的数学符号计算库,用它可以进行数学公式的符号推导.为了调用方便,下面所有的实例程序都假设事先从sympy库导入了所有内容: >>> ...