sabato 20 agosto 2016

A cosa serve il Cross Join


A chiunque sarà capitato di vedere una tabella così disegnata, a spregio della 1NF


Tabella T1



Cliente Y VGen VFeb VMar VApr VMag VGiu VLug VAgo VSet VOtt VNov VDic
10 2016 12 11 22 33 34 12 33 44 21 12 11 1







Il problema era quindi di normalizzare quindi riportare in riga le 12 colonne. Oracle ha la sua bella unpivot ma sul db2 (in attesa della unpivot, e della pivot, magari) si può fare in differenti modi:

con le union, funziona sicuramente ma è tremendamente dispendioso dal punto di vista prestazionale:

create view V1 (Cliente, Y, ValMese) as
select Cliente, Y, cast(1 as decimal(2, 0)), VGen union
select Cliente, Y, 2, VFeb union
select Cliente, Y, 3, VMar union
select Cliente, Y, 4, VApr union
select Cliente, Y, 5, VMag union
select Cliente, Y, 6, VGiu union
select Cliente, Y, 7, VLug union
select Cliente, Y, 8, VAgo union
select Cliente, Y, 9, VSet union
select Cliente, Y, 10, VOtt union
select Cliente, Y, 11, VNov union
select Cliente, Y, 12, VDic


Utilizzando la Cross Join:

Creiamo una tabella T2 che contiene i dodici mesi:
CREATE TABLE $SWAP/T2 (MESE DECIMAL (2 , 0) NOT NULL WITH DEFAULT,
CONSTRAINT T2_PK PRIMARY KEY (MESE), CONSTRAINT T2_CHECK CHECK   
(mese >= 1 and mese <=12 ))                                       

INSERT INTO $SWAP/T2 VALUES(1), (2), (3), (4), (5), (6), (7), (8),
(9), (10), (11), (12)

Con la Cross Join si riesce ad ottenere quanto desiderato:
create view V2 (cliente, y, mese, valmese) as    
select cliente, y, mese,                         
case mese                                         
when 1  then Vgen                                
when 2  then Vfeb                                
when 3  then Vmar                                
when 4  then Vapr                                
when 5  then Vmag                                 
when 6  then Vgiu                                
when 7  then Vlug                                
when 8  then Vago                                
when 9  then Vset                                
when 10 then Vott                                
when 11 then Vnov                                
when 12 then Vdic                                
end as ValMese                                   
from $swap.T1 cross join $swap.T2           


Dalla 6.1 il dataset T2 (mesi) può essere popolato on-the-fly, non è più necessari la tabella T2, o meglio, la si può virtualizzare:

create view V3 (cliente, y, mese, valmese) as    
select cliente, y, mese,                         
case mese                                         
when 1  then Vgen                                
when 2  then Vfeb                                
when 3  then Vmar                                
when 4  then Vapr                                
when 5  then Vmag                                 
when 6  then Vgiu                                
when 7  then Vlug                                
when 8  then Vago                                
when 9  then Vset                                
when 10 then Vott                                
when 11 then Vnov                                
when 12 then Vdic                                
end as ValMese                                   
from $swap.T1 cross join
 (VALUES(1), (2), (3), (4), (5), (6), (7), (8),
(9), (10), (11), (12)) as T2(mese)

Nessun commento:

Posta un commento