venerdì 28 aprile 2017

RDBMS ORACLE - Coverting String Column to row

Può capitare di avere in una colonna di una tabella dei valori stringa che occorre verticalizzare, ma il problema è che occorre effettuare la verticalizzazione senza utilizzare pl-sql ma solo una query sql.
Allora uno pensa utilizzaziamo le funzioni di UNPIVOT o PIVOT e no quelle funzionano per inserire i dati in una colonna e nel nostro caso non vanno bene.
Supponiamo di avere in un campo di una tabella i seguenti valori:

TEMPLATE             
-----------------------
A.A.A_B.D.D           
A.HH_B.GGG_C.L.L_D.KK.J
S.S_S.D.D             

Quello che dobbiamo avere in output è che in corrispondenza degli "_"  verticalizziamo il risultato. Quindi il risultato finale deve essere:

TEMPLATE             
-----------------------
A.A.A
B.D.D           
A.HH

B.GGG
C.L.L
D.KK.J
S.S

S.D.D             

Il problema in questo caso è che dobbiamo fare un ciclo in sql per poter splittare il risultato presente nella colonna.
Come facciamo?
Di seguito una semplice query che ci permette di ottenere il risultato voluto.

WITH
   TEST AS (SELECT TEMPLATE ,regexp_count(TEMPLATE, '_') REG_C FROM
                 (SELECT 'A.A.A_B.D.D' TEMPLATE FROM DUAL UNION ALL
                 SELECT 'A.HH_B.GGG_C.L.L_D.KK.J' TEMPLATE FROM DUAL UNION ALL
                 SELECT 'S.S_S.D.D' TEMPLATE FROM DUAL)),
    MX AS (SELECT MAX(REGEXP_COUNT(TEMPLATE, '_'))+1 CC FROM TEST)
SELECT  STRING_VERTICALE,TEMPLATE_ORIGINALE,REG_C,RN
 FROM
(
SELECT  CASE WHEN REG_C>0 THEN
          SUBSTR(regexp_substr(TTEST.TEMPLATE, '[^_]+', 1, MXX.RN), 0, LENGTH(regexp_substr(TTEST.TEMPLATE, '[^_]+', 1, MXX.RN)))
          ELSE TTEST.TEMPLATE  END STRING_VERTICALE,
          TTEST.TEMPLATE TEMPLATE_ORIGINALE,TTEST.REG_C,MXX.RN
FROM
(SELECT TEMPLATE, REG_C FROM TEST) TTEST  ,
(SELECT ROWNUM RN FROM CAT WHERE ROWNUM <=(SELECT CC FROM MX))  MXX
  )
WHERE STRING_VERTICALE IS NOT NULL;


Il risultato ottenuto è il seguente:





Nessun commento:

Posta un commento