Progettazione di schemi semplici per la disaggregazione della previsione della domanda


9

Sto svolgendo una semplice attività di progettazione di database come esercizio di formazione in cui devo elaborare una progettazione di schema di base per il caso seguente:

Ho una gerarchia di prodotti genitore-figlio (ad esempio, Materie prime> Lavori in corso> Prodotto finale).

  • Gli ordini vengono effettuati ad ogni livello.
  • Il numero di ordini sarà visualizzabile in secchi settimanali per i prossimi 6 mesi.
  • La previsione della domanda può essere fatta per ogni livello di prodotto.
  • Le previsioni della domanda per ogni settimana entro i prossimi 6 mesi possono essere fatte oggi.
  • La previsione della domanda viene eseguita per bucket settimanali, per i prossimi 6 mesi.

La previsione della domanda viene solitamente effettuata a livello superiore nella gerarchia (livello di materie prime o lavori in corso). Deve essere disaggregata a un livello inferiore (prodotto finale).

Esistono 2 modi in cui le previsioni della domanda possono essere disaggregate da un livello superiore a un livello inferiore:

  1. L'utente specifica la distribuzione percentuale per il prodotto finale. Supponiamo che ci sia una previsione di 1000 per Work In Progress .. e l'utente dice che desidero il 40% per il prodotto finale 1 e il 60% per il prodotto finale 2 nel bucket 10 .. Quindi per la decima settimana (da domenica a sabato) da ora, valore di previsione per il prodotto finale 1 sarebbe 400 e, per il prodotto finale 2 sarebbe 600.
  2. L'utente dice, basta disaggregare in base agli ordini effettuati rispetto ai prodotti finali nel bucket 5 e gli ordini nel bucket 5 per il prodotto finale 1 e 2 sono rispettivamente 200 e 800, quindi il valore di previsione per EP1 sarebbe ((200/1000) * 100)% e per EP2 sarebbe ((800/1000) * 100)% delle previsioni per "Lavori in corso".

Le previsioni devono essere visualizzate in intervalli settimanali per i prossimi 6 mesi e il formato ideale dovrebbe essere:

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

La tabella PRODUCT_HIERARCHY potrebbe apparire così:

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

La tabella ORDINI potrebbe apparire così:

id | prod_id | order_date | delivery_date | delivered_date

dove,

prod_idè una chiave esterna che fa riferimento idalla tabella PRODUCT_HIERARCHY,

Come memorizzare le previsioni? Quale sarebbe un buon schema di base per un tale requisito?


La mia idea di selezionare ordini per 26 secchi settimanali è:

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

Ma questo darà secchi settimanali a partire da oggi indipendentemente dal giorno. Come posso convertirli in settimane da domenica a sabato in Oracle?

Aiutate a progettare questa struttura di database.

(utilizzerà Oracle 11g)


1
sembra che tu stia costruendo un data warehouse. l'ordine sarebbe la tabella dei fatti. prodotto e data le tabelle delle dimensioni. È possibile che si desideri utilizzare una tabella dei fatti cumulativa, poiché si sta esaminando un processo che prevede diversi passaggi.
Neil McGuigan,

Risposte:


1

Ok, quindi ecco il modello di dati che ho ideato.

PRODOTTO - per memorizzare informazioni sul prodotto e mantenere la gerarchia genitore-figlio

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)                  

ORDINI - per archiviare gli ordini di prodotti

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"

PREVISIONE - per memorizzare il valore di previsione per i prodotti (valore del negozio per livelli più alti, valore del negozio per livelli più bassi dopo la disaggregazione da un genitore)

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 - per memorizzare quale metodo è stato utilizzato per disaggregare un valore da un livello superiore a un livello inferiore e quanta percentuale è stata distribuita al livello inferiore

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 - dimensione data, contiene informazioni sulla data di inizio (deve essere sabato) e la data di fine corrispondente alla settimana in cui cade una data particolare

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

Per quanto riguarda il numero di bucket ... Sto calcolando la data di inizio della settimana (data sabato, nel mio caso) con la seguente funzione

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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.