Conception d'un schéma simple pour la désagrégation de la prévision de la demande

9

Je fais une tâche de conception de base de données simple comme un exercice de formation où je dois proposer une conception de schéma de base pour le cas suivant:

J'ai une hiérarchie parent-enfant de produits (par exemple, Matière première> Travail en cours> Produit final).

  • Les commandes sont passées à chaque niveau.
  • Le nombre de commandes sera visible dans des seaux hebdomadaires pour les 6 prochains mois.
  • La prévision de la demande peut être effectuée pour chaque niveau de produit.
  • La prévision de la demande pour n'importe quelle semaine dans les 6 prochains mois peut être faite aujourd'hui.
  • La prévision de la demande se fait pour les seaux hebdomadaires, pour les 6 prochains mois.

La prévision de la demande est généralement effectuée au niveau supérieur de la hiérarchie (niveau des matières premières ou des travaux en cours). Elle doit être ventilée à un niveau inférieur (produit final).

Il existe deux façons de désagréger la prévision de la demande d'un niveau supérieur à un niveau inférieur:

  1. L'utilisateur spécifie la distribution en pourcentage du produit final. Disons, il y a une prévision de 1000 pour le travail en cours .. et l'utilisateur dit que je veux 40% pour le produit final 1 et 60% pour le produit final 2 dans le compartiment 10 .. Ensuite, pour la 10e semaine (du dimanche au samedi) à partir de maintenant, la valeur de prévision pour le produit final 1 serait 400 et, pour le produit final 2 serait 600.
  2. L'utilisateur dit, juste désagréger selon les commandes passées contre les produits finaux dans le compartiment 5, et les commandes dans le compartiment 5 pour le produit final 1 et 2 sont respectivement de 200 et 800, alors la valeur prévue pour EP1 serait ((200/1000) * 100)% et pour EP2 serait ((800/1000) * 100)% des prévisions pour les «travaux en cours».

Les prévisions doivent être consultables par tranches hebdomadaires pour les 6 prochains mois et le format idéal doit être:

product name | bucket number | week start date | week end date | forecast value | created_on

La table PRODUCT_HIERARCHY pourrait ressembler à ceci:

id  |   name                |   parent_id
__________________________________________
1   |   raw material        |   (null)
2   |   work in progress    |   1
3   |   end product 1       |   2
4   |   end product 2       |   2

La table ORDERS pourrait ressembler à ceci:

id | prod_id | order_date | delivery_date | delivered_date

où,

prod_idest une clé étrangère qui fait référence à la idtable PRODUCT_HIERARCHY,

Comment stocker les prévisions? Quel serait un bon schéma de base pour une telle exigence?


Mon idée pour sélectionner les commandes de 26 seaux hebdomadaires est la suivante:

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);

Mais cela donnera des seaux hebdomadaires à partir d'aujourd'hui, quel que soit le jour. Comment puis-je les convertir en semaines du dimanche au samedi dans Oracle?

Aidez-nous à concevoir cette structure de base de données.

(utilisera Oracle 11g)

Abhinav Sood
la source
1
sonne comme si vous construisez un entrepôt de données. l'ordre serait la table des faits. produit et datez les tableaux de dimensions. Vous voudrez peut-être utiliser une table de faits accumulée, car vous regardez un processus qui comporte plusieurs étapes.
Neil McGuigan

Réponses:

1

D'accord, voici donc le modèle de données que j'ai trouvé.

PRODUIT - pour stocker des informations sur le produit et maintenir la hiérarchie parent-enfant

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)                  

COMMANDES - pour stocker les commandes de produits

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"

PREVISION - pour stocker la valeur prévisionnelle des produits (valeur magasin pour les niveaux supérieurs, valeur magasin pour les niveaux inférieurs après désagrégation d'un parent)

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 - pour stocker la méthode utilisée pour désagréger une valeur d'un niveau supérieur à un niveau inférieur et combien de pourcentage a été distribué à un niveau inférieur

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 - dimension de date, contient des informations sur la date de début (doit être samedi) et la date de fin correspondant à la semaine au cours de laquelle une date particulière tombe

date_key    NUMBER  "Primary Key
Not Null"                   
full_date   DATE    Not Null                    
week_begin_date DATE    Not Null                    
week_end_date   DATE    Not Null

Quant au numéro de compartiment. Je calcule la date de début de la semaine (date du samedi, dans mon cas) avec la fonction suivante

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;
Abhinav Sood
la source