Разработка простой схемы дезагрегации прогноза спроса


9

Я выполняю простую задачу проектирования базы данных в качестве учебного упражнения, в котором мне нужно придумать базовую схему схемы для следующего случая:

У меня есть родительско-дочерняя иерархия продуктов (например, Сырье> Незавершенное производство> Конечный продукт).

  • Заказы размещаются на каждом уровне.
  • Количество заказов должно отображаться в еженедельных корзинах в течение следующих 6 месяцев.
  • Прогноз спроса может быть сделан для каждого уровня продукта.
  • Прогноз спроса на любую неделю в течение следующих 6 месяцев можно сделать сегодня.
  • Прогноз спроса сделан для еженедельных периодов на следующие 6 месяцев.

Прогноз спроса обычно делается на более высоком уровне в иерархии (сырье или уровень незавершенного производства). Он должен быть дезагрегирован до более низкого уровня (конечный продукт).

Существует два способа дезагрегирования прогноза спроса с более высокого уровня на более низкий уровень:

  1. Пользователь указывает процентное распределение для конечного продукта. Скажем, есть прогноз 1000 для Work In Progress ... и пользователь говорит, что я хочу 40% для конечного продукта 1 и 60% для конечного продукта 2 в сегменте 10 .. Затем для 10-й недели (с воскресенья по субботу), прогнозное значение для конечного продукта 1 будет 400, а для конечного продукта 2 будет 600.
  2. Пользователь говорит, что просто выполните дезагрегацию в соответствии с заказами, размещенными для конечных продуктов в сегменте 5, и порядками в сегменте 5 для конечного продукта 1 и 2 соответственно 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

Таблица 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

Таблица ORDERS может выглядеть так:

id | prod_id | order_date | delivery_date | delivered_date

где,

prod_idэто внешний ключ, который ссылается idна таблицу PRODUCT_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);

Но это даст еженедельные интервалы, начиная с сегодняшнего дня, независимо от дня. Как я могу преобразовать их в воскресенье в субботу недели в Oracle?

Пожалуйста, помогите разработать эту структуру базы данных.

(будет использовать Oracle 11g)


1
Похоже, вы строите хранилище данных. порядок будет таблица фактов. продукт и дата таблицы измерений. Возможно, вы захотите использовать таблицу фактов накопления, поскольку вы смотрите на процесс, который имеет несколько шагов.
Нил Макгиган

Ответы:


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)                  

ЗАКАЗЫ - хранить заказы на продукцию

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"

ПРОГНОЗ - сохранить прогнозное значение для продуктов (сохранить значение для более высоких уровней, сохранить значение для более низких уровней после разукрупнения от родителя)

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"                   

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                    

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

Что касается номера корзины. Я рассчитываю дату начала недели (в моем случае, дату в субботу) с помощью следующей функции

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;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.