Oracle
 sql >> Database >  >> RDS >> Oracle

Suddivisione della stringa in più righe in Oracle

Questo potrebbe essere un modo migliore (anche con regexp e connect by):

with temp as
(
    select 108 Name, 'test' Project, 'Err1, Err2, Err3' Error  from dual
    union all
    select 109, 'test2', 'Err1' from dual
)
select distinct
  t.name, t.project,
  trim(regexp_substr(t.error, '[^,]+', 1, levels.column_value))  as error
from 
  temp t,
  table(cast(multiset(select level from dual connect by  level <= length (regexp_replace(t.error, '[^,]+'))  + 1) as sys.OdciNumberList)) levels
order by name

MODIFICA :Ecco una spiegazione semplice (come in "non in profondità") della query.

  1. length (regexp_replace(t.error, '[^,]+')) + 1 utilizza regexp_replace per cancellare tutto ciò che non è il delimitatore (virgola in questo caso) e length +1 per ottenere quanti elementi (errori) ci sono.
  2. Il select level from dual connect by level <= (...) utilizza una query gerarchica per creare una colonna con un numero crescente di corrispondenze trovate, da 1 al numero totale di errori.

    Anteprima:

    select level, length (regexp_replace('Err1, Err2, Err3', '[^,]+'))  + 1 as max 
    from dual connect by level <= length (regexp_replace('Err1, Err2, Err3', '[^,]+'))  + 1
    
  3. table(cast(multiset(.....) as sys.OdciNumberList)) esegue alcuni casting di tipi di oracoli.
    • Il cast(multiset(.....)) as sys.OdciNumberList trasforma più raccolte (una raccolta per ogni riga nel set di dati originale) in un'unica raccolta di numeri, OdciNumberList.
    • La table() la funzione trasforma una raccolta in un set di risultati.
  4. FROM senza un join crea un incrocio incrociato tra il tuo set di dati e il multiset. Di conseguenza, una riga nel set di dati con 4 corrispondenze si ripeterà 4 volte (con un numero crescente nella colonna denominata "column_value").

    Anteprima:

    select * from 
    temp t,
    table(cast(multiset(select level from dual connect by  level <= length (regexp_replace(t.error, '[^,]+'))  + 1) as sys.OdciNumberList)) levels
    
  5. trim(regexp_substr(t.error, '[^,]+', 1, levels.column_value)) utilizza il column_value come ennesima_apparizione/occorrenza parametro per regexp_substr .
  6. Puoi aggiungere altre colonne dal tuo set di dati (t.name, t.project ad esempio) per una facile visualizzazione.

Alcuni riferimenti ai documenti Oracle:

  • REGEXP_REPLACE
  • REGEXP_SUBSTR
  • Costanti, tipi e mappature di estendibilità (OdciNumberList)
  • CAST (multiset)
  • Query gerarchiche