我正在处理我有
的案例我的目标是根据这些孩子的订单数量,将特定周的特定RM或WIP的预测值分解为该特定周的该RM或WIP的部分或全部子EP。
这只是意味着如果我有一个RM,比如RM1,它有3个子EP,比如说EP1,EP2和EP3 ..而且我对第2周的RM1预测值为1000,那么我的目标就是拆分根据每个EP的计算或指定百分比分布,将此预测分为3个部分。
用户可以选择使用哪种方法获取百分比分配:
计算 :用户说,根据第10到第15桶的订单(从现在开始的第10周)将RM1预测值分解为EP1和EP2从现在开始的日期到第16周)。因此,我们分别从第10周到第15周每桶计算EP1和EP2的总订单,并按如下方式计算百分比分布:EP1订单/(EP1 + EP2订单)* 100%和(EP2订单)/(EP1 + EP2订单)* 100%分别。
指定 :用户说,EP1为20%,EP2为50%,EP3为10%
然后我们根据我们计算或得到的百分比,将每个EP的第2周RM1预测值除以1000,并将其作为第2周EP的预测值存储在同一个表中。
选择分解的方法与parent_id,child_id,子女的百分比,开始桶的开始日期,(结束桶+ 1)的开始日期一起存储在另一个表中
我有以下表格:
我在这里发布了我的数据模型:https://stackoverflow.com/a/14881277/891424这里是我迄今为止编写的一个函数和几个过程:
查找与给定存储桶对应的周开始日期的功能
CREATE OR REPLACE FUNCTION get_week_start_date(v_bucket_num IN NUMBER)
RETURN DATE
IS
week_start_date DATE;
BEGIN
SELECT (TRUNC(SYSDATE+2, 'IW')-2) + ((v_bucket_num-1) * 7)
INTO week_start_date FROM dual;
RETURN week_start_date;
END;
返回给定父级的所有子EP的过程
CREATE OR REPLACE PROCEDURE get_eps(
v_parent IN NUMBER,
v_children_of_parent OUT SYS_REFCURSOR
)
AS
v_children SYS_REFCURSOR;
BEGIN
OPEN v_children_of_parent FOR
SELECT id, name FROM (
SELECT
CONNECT_BY_ISLEAF isleaf, p.id, p.name
FROM
inf_product p
WHERE p.level_code = 'EP'
START WITH id = 1
CONNECT BY PRIOR id = parent_id
)
WHERE isleaf = 1;
END;
执行预测值分解的程序(不完整)
CREATE OR REPLACE PROCEDURE inf_disaggregate(v_parent_id IN NUMBER, v_bucket_start IN NUMBER, v_bucket_end IN NUMBER)
IS
/* Parent Product ID from input */
v_parent_prod_id NUMBER;
/* All the children of parent specified in the input */
child_cursor SYS_REFCURSOR;
child_id NUMBER;
child_name VARCHAR2(40);
/* Forecast Bucket Info */
vbucket_start NUMBER;
vbucket_end NUMBER;
vbucket_diff NUMBER; -- loop over vbucket_diff + 1
/* Date corresponding to input buckets */
vbucket_start_date DATE;
vbucket_end_date DATE;
/* Exceptions */
invalid_bucket EXCEPTION;
PRAGMA EXCEPTION_INIT( invalid_bucket, -20001 );
BEGIN
v_parent_prod_id := v_parent_id;
vbucket_start := v_bucket_start;
vbucket_end := v_bucket_end;
vbucket_diff := vbucket_end - vbucket_start;
IF vbucket_diff < 0 THEN
RAISE_APPLICATION_ERROR( -20001, 'Bucket numbers not in the correct order' );
END IF;
IF vbucket_start < 1 OR vbucket_start > 26 OR vbucket_end < 1 OR vbucket_end > 26 THEN
RAISE_APPLICATION_ERROR( -20001, 'Bucket value must be within 1 to 26' );
END IF;
/* Get first day of the week corresponding to the buckets */
vbucket_start_date := get_week_start_date(vbucket_start);
vbucket_end_date := get_week_start_date(vbucket_end);
DBMS_OUTPUT.PUT_LINE(vbucket_start);
DBMS_OUTPUT.PUT_LINE(vbucket_end);
DBMS_OUTPUT.PUT_LINE(vbucket_diff);
DBMS_OUTPUT.PUT_LINE(vbucket_start_date);
DBMS_OUTPUT.PUT_LINE(vbucket_end_date);
/* Get all child EPs for the specified parent */
get_eps(v_parent => v_parent_prod_id, v_children_of_parent => child_cursor);
LOOP
FETCH child_cursor
INTO child_id, child_name;
EXIT WHEN child_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(child_id || ' | ' || child_name);
END LOOP;
CLOSE child_cursor;
EXCEPTION
WHEN invalid_bucket
THEN
DBMS_OUTPUT.PUT_LINE(SUBSTR(SQLERRM, 1 , 80));
END;
/
运行程序
SET SERVEROUTPUT ON;
CALL inf_disaggregate(5, 10, 12);
问题1:如何创建包或程序来完成此任务?
问题2:如何摆脱SYS_REFCURSOR并改用动态sql? (我可能也应该摆脱child_name,因为只有ID才能满足所有目的)
问题3 :如何获取分解方法以及 指定 ,百分比作为用户输入?