Informaticamente la distinta base è di solito gestita con una tabella che presenta la seguente struttura:
CODICE PADRE, CODICE FIGLIO, COEF
Presentando una relazione ricorsiva tra codice padre e figlio, ovvero una distinta cosi composta:
viene rappresentata in tabella in questo modo:
PADRE | FIGLIO | COEF |
A001 | B001 |
1 |
A001 | B002 |
1 |
B001 | C001 |
1 |
B001 | C002 |
1 |
B002 | C003 |
1 |
B002 | C004 |
1 |
A partire da questa struttura è possibile effettuare le seguenti elaborazioni:
1. Esplosione: A partire da un codice padre vengono individuati tutti i codici della distinta
2. Implosione: A partire da un codice figlio vengono individuati i codici padri che hanno quel figlio
3. Materiale di base: simile ad Esplosione ma non vengono considerati i semilavorati.
4. Prodotti finiti: simile ad Implosione ma non vengono considerati i semilavorati.
È possibile effettuare queste operazioni tramite SQL oppure tramite una funzione ricorsiva, in questo post vedremo come effettuare queste operazioni tramite SQL. Unica condizione per applicare le operazioni in SQL è conoscere il livello massimo di profondità della distinta in modo da individuare quante ricorsioni effettuare, per il nostro esempio confideremo un livello massimo pari a 5.
Esplosione distinta
SELECT CODICE.CODICE, DISTINTA.FIGLIO AS C1, DISTINTA_1.FIGLIO AS C2, DISTINTA_2.FIGLIO AS C3, DISTINTA_3.FIGLIO AS C4, DISTINTA_4.FIGLIO AS C5, DISTINTA.COEF AS CO1, DISTINTA_1.COEF AS CO2, DISTINTA_2.COEF AS CO3, DISTINTA_3.COEF AS CO4, DISTINTA_4.COEF AS CO5 INTO [distinta eslposa] FROM CODICE LEFT JOIN ((((DISTINTA LEFT JOIN DISTINTA AS DISTINTA_1 ON DISTINTA.FIGLIO = DISTINTA_1.PADRE) LEFT JOIN DISTINTA AS DISTINTA_2 ON DISTINTA_1.FIGLIO = DISTINTA_2.PADRE) LEFT JOIN DISTINTA AS DISTINTA_3 ON DISTINTA_2.FIGLIO = DISTINTA_3.PADRE) LEFT JOIN DISTINTA AS DISTINTA_4 ON DISTINTA_3.FIGLIO = DISTINTA_4.PADRE) ON CODICE.CODICE = DISTINTA.PADRE; |
SELECT CODICE.CODICE, DISTINTA.FIGLIO AS C1, DISTINTA_1.FIGLIO AS C2, DISTINTA_2.FIGLIO AS C3, DISTINTA_3.FIGLIO AS C4, DISTINTA_4.FIGLIO AS C5, DISTINTA.COEF AS CO1, DISTINTA_1.COEF AS CO2, DISTINTA_2.COEF AS CO3, DISTINTA_3.COEF AS CO4, DISTINTA_4.COEF AS CO5 INTO [distinta eslposa] FROM CODICE LEFT JOIN ((((DISTINTA LEFT JOIN DISTINTA AS DISTINTA_1 ON DISTINTA.FIGLIO = DISTINTA_1.PADRE) LEFT JOIN DISTINTA AS DISTINTA_2 ON DISTINTA_1.FIGLIO = DISTINTA_2.PADRE) LEFT JOIN DISTINTA AS DISTINTA_3 ON DISTINTA_2.FIGLIO = DISTINTA_3.PADRE) LEFT JOIN DISTINTA AS DISTINTA_4 ON DISTINTA_3.FIGLIO = DISTINTA_4.PADRE) ON CODICE.CODICE = DISTINTA.PADRE;
A questo punto raggruppiamo livello per livello i codici.
Implosione distinta
SELECT CODICE.CODICE, DISTINTA.PADRE AS C1, DISTINTA_1.PADRE AS C2, DISTINTA_2.PADRE AS C3, DISTINTA_3.PADRE AS C4, DISTINTA_4.PADRE AS C5, DISTINTA.COEF AS CO1, DISTINTA_1.COEF AS CO2, DISTINTA_2.COEF AS CO3, DISTINTA_3.COEF AS CO4, DISTINTA_4.COEF AS CO5 INTO [distinta implosa] FROM CODW LEFT JOIN ((((DISTINTA LEFT JOIN DISTINTA AS DISTINTA_1 ON DISTINTA.PADRE = DISTINTA_1.FIGLIO) LEFT JOIN DISTINTA AS DISTINTA_2 ON DISTINTA_1.PADRE = DISTINTA_2.FIGLIO) LEFT JOIN DISTINTA AS DISTINTA_3 ON DISTINTA_2.PADRE = DISTINTA_3.FIGLIO) LEFT JOIN DISTINTA AS DISTINTA_4 ON DISTINTA_3.PADRE = DISTINTA_4.FIGLIO) ON CODICE.CODICE = DISTINTA.FIGLIO; |
SELECT CODICE.CODICE, DISTINTA.PADRE AS C1, DISTINTA_1.PADRE AS C2, DISTINTA_2.PADRE AS C3, DISTINTA_3.PADRE AS C4, DISTINTA_4.PADRE AS C5, DISTINTA.COEF AS CO1, DISTINTA_1.COEF AS CO2, DISTINTA_2.COEF AS CO3, DISTINTA_3.COEF AS CO4, DISTINTA_4.COEF AS CO5 INTO [distinta implosa] FROM CODW LEFT JOIN ((((DISTINTA LEFT JOIN DISTINTA AS DISTINTA_1 ON DISTINTA.PADRE = DISTINTA_1.FIGLIO) LEFT JOIN DISTINTA AS DISTINTA_2 ON DISTINTA_1.PADRE = DISTINTA_2.FIGLIO) LEFT JOIN DISTINTA AS DISTINTA_3 ON DISTINTA_2.PADRE = DISTINTA_3.FIGLIO) LEFT JOIN DISTINTA AS DISTINTA_4 ON DISTINTA_3.PADRE = DISTINTA_4.FIGLIO) ON CODICE.CODICE = DISTINTA.FIGLIO;
A questo punto raggruppiamo livello per livello i codici.
Per ottenere i materiali di base ed i prodotti finiti è necessario fare un’ulteriore operazione a partire dalle tabelle distinta implosa e distinta esplosa.
Materiali di base
SELECT [distinta eslposa].[PADRE], IIf([C5] IS NOT NULL,[C5],IIf([C4] IS NOT NULL,[C4],IIf([C3] IS NOT NULL,[C3],IIf([C2] IS NOT NULL,[C2],IIf([C1] IS NOT NULL,[C1],NULL))))) AS FIGLIO, nz([CO1],1)*nz([CO2],1)*nz([CO3],1)*nz([CO4],1)*nz([CO5],1) AS COEF FROM [distinta eslposa]; |
SELECT [distinta eslposa].[PADRE], IIf([C5] Is Not Null,[C5],IIf([C4] Is Not Null,[C4],IIf([C3] Is Not Null,[C3],IIf([C2] Is Not Null,[C2],IIf([C1] Is Not Null,[C1],Null))))) AS FIGLIO, nz([CO1],1)*nz([CO2],1)*nz([CO3],1)*nz([CO4],1)*nz([CO5],1) AS COEF FROM [distinta eslposa];
Prodotti finiti
SELECT [distinta implosa].CODICE, IIf([C5] IS NOT NULL,[C5],IIf([C4] IS NOT NULL,[C4],IIf([C3] IS NOT NULL,[C3],IIf([C2] IS NOT NULL,[C2],IIf([C1] IS NOT NULL,[C1],NULL))))) AS PADRE, nz([CO1],1)*nz([CO2],1)*nz([CO3],1)*nz([CO4],1)*nz([CO5],1) AS COEF FROM [distinta implosa]; |
SELECT [distinta implosa].CODICE, IIf([C5] Is Not Null,[C5],IIf([C4] Is Not Null,[C4],IIf([C3] Is Not Null,[C3],IIf([C2] Is Not Null,[C2],IIf([C1] Is Not Null,[C1],Null))))) AS PADRE, nz([CO1],1)*nz([CO2],1)*nz([CO3],1)*nz([CO4],1)*nz([CO5],1) AS COEF FROM [distinta implosa];
Queste elaborazioni costituiscono la base per successive altre elaborazioni come il confronto tra distinte o l’analisi dei codici dedicati ecc.