设计分解需求预测的简单模式

Abh*_*ood 9 schema oracle database-design oracle-11g

我正在做一个简单的数据库设计任务作为培训练习,我必须为以下情况提出一个基本的模式设计:

我有一个产品的父子层次结构(例如,原材料 > 在制品 > 最终产品)。

  • 订单被放置在每个级别。
  • 在接下来的 6 个月内,订单数量应在每周的桶中可见。
  • 可以对每个产品级别进行需求预测。
  • 未来 6 个月内任何一周的需求预测都可以在今天完成。
  • 对未来 6 个月的每周桶进行需求预测。

需求预测通常在层次结构的较高级别(原材料或在制品级别)完成,它必须分解到较低级别(最终产品)。

有两种方法可以将需求预测从较高级别分解到较低级别:

  1. 用户指定最终产品的百分比分布。比如说,有 1000 个正在进行的工作的预测......并且用户说我想要 40% 的最终产品 1 和 60% 的最终产品 2 在桶 10 中......然后从现在开始的第 10 周(周日到周六),预测值最终产品 1 为 400,最终产品 2 为 600。
  2. 用户说,只需根据桶5中最终产品的订单进行分解,最终产品1和2的桶5中的订单分别为200和800,那么EP1的预测值为((200/1000)* 100)%对于 EP2,将是“正在进行的工作”预测的 ((800/1000) * 100)%。

未来 6 个月的每周预测应可见,理想的格式应为:

product name | bucket number | week start date | week end date | forecast value | created_on
Run Code Online (Sandbox Code Playgroud)

PRODUCT_HIERARCHY表可能如下所示:

id  |   name                |   parent_id
__________________________________________
1   |   raw material        |   (null)
2   |   work in progress    |   1
3   |   end product 1       |   2
4   |   end product 2       |   2
Run Code Online (Sandbox Code Playgroud)

ORDERS可能如下所示:

id | prod_id | order_date | delivery_date | delivered_date
Run Code Online (Sandbox Code Playgroud)

在哪里,

prod_id是引用idPRODUCT_HIERARCHY 表的外键,

如何存储预测? 对于这种需求,什么是好的基本模式?


我选择每周 26 个桶的订单的想法是:

SELECT
    COUNT(*) TOTAL_ORDERS,
    WIDTH_BUCKET(
        delivery_date,
        SYSDATE,
        ADD_MONTHS(sysdate, 6), 
        TO_NUMBER( TO_CHAR(SYSDATE,'DD-MON-YYYY') - TO_CHAR(ADD_MONTHS(sysdate, 6),'DD-MON-YYYY') ) / 7
    ) BUCKET_NO
FROM
    orders_table
WHERE
    delivery_date BETWEEN SYSDATE AND ADD_MONTHS(sysdate, 6);
Run Code Online (Sandbox Code Playgroud)

但这将提供从今天开始的每周桶,而不管哪一天。如何在 Oracle 中将它们转换为周日到周六周?

请帮助设计这个数据库结构。

(将使用 Oracle 11g)

Abh*_*ood 1

好的,这是我想出的数据模型。

PRODUCT——存储产品信息并维护父子层次结构

id  NUMBER  "Primary Key Not Null"                  
level_code  VARCHAR2    Not Null                    
name    VARCHAR2    Not Null                    
description VARCHAR2                        
parent_id   NUMBER  Foreign Key references PRODUCT(id)                  
Run Code Online (Sandbox Code Playgroud)

ORDERS——存储产品订单

id  NUMBER  "Primary Key Not Null"                  
prod_id     NUMBER  "Foreign Key references PRODUCT(id) Not Null"                   
order_type  VARCHAR2    "Not Null Default 'Default'"
order_qty   NUMBER  Not Null
order_date  NUMBER  Foreign Key references DATE_INFO(date_key)
delivery_date   NUMBER  "Foreign Key references DATE_INFO(date_key)
Check delivery_date >= order_date"
Run Code Online (Sandbox Code Playgroud)

FORECAST——存储产品的预测值(存储较高级别的值,存储从父级分解后较低级别的值)

id  NUMBER  "Primary Key Not Null"
product_id  NUMBER  "Foreign Key references PRODUCT(id) Not Null"
forecast_value  NUMBER  Not Null
week    NUMBER  "Foreign Key references DATE_INFO(date_key) Not Null"                   
Run Code Online (Sandbox Code Playgroud)

DISAGGREGATION_RULES——存储使用哪种方法将值从较高级别分解到较低级别以及分配到较低级别的百分比

id  NUMBER  "Primary Key Not Null"
parent_product_id   NUMBER  "Foreign Key id references PRODUCT(id) Not Null"
child_product_id    NUMBER  "Foreign Key id references PRODUCT(id) Not Null"
method  VARCHAR2    Not Null                    
from_week   NUMBER  "Foreign Key references DATE_INFO(date_key) Not Null"
to_week NUMBER  "Foreign Key references DATE_INFO(date_key) Not Null Check end_week >= start_week"
percent_distribution    NUMBER  Not Null                    
Run Code Online (Sandbox Code Playgroud)

DATE_INFO -- 日期维度,包含与特定日期所在周相对应的开始日期(必须是星期六)和结束日期的信息

date_key    NUMBER  "Primary Key
Not Null"                   
full_date   DATE    Not Null                    
week_begin_date DATE    Not Null                    
week_end_date   DATE    Not Null
Run Code Online (Sandbox Code Playgroud)

至于桶号..我正在使用以下函数计算周开始日期(在我的情况下是星期六的日期)

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;
Run Code Online (Sandbox Code Playgroud)