sql >> Base de Datos >  >> RDS >> Oracle

Dividir cadena en varias filas en Oracle

Esta puede ser una forma mejorada (también con regexp y 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

EDITAR :Aquí hay una explicación simple (como en "no en profundidad") de la consulta.

  1. length (regexp_replace(t.error, '[^,]+')) + 1 usa regexp_replace para borrar cualquier cosa que no sea el delimitador (coma en este caso) y length +1 para obtener cuántos elementos (errores) hay.
  2. El select level from dual connect by level <= (...) utiliza una consulta jerárquica para crear una columna con un número creciente de coincidencias encontradas, de 1 al número total de errores.

    Vista previa:

    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)) hace algo de conversión de tipos de oráculos.
    • El cast(multiset(.....)) as sys.OdciNumberList transforma varias colecciones (una colección para cada fila en el conjunto de datos original) en una sola colección de números, OdciNumberList.
    • La table() La función transforma una colección en un conjunto de resultados.
  4. FROM sin una unión crea una unión cruzada entre su conjunto de datos y el conjunto múltiple. Como resultado, una fila en el conjunto de datos con 4 coincidencias se repetirá 4 veces (con un número creciente en la columna denominada "column_value").

    Vista previa:

    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)) usa el column_value como la nth_appearance/ocurrencia parámetro para regexp_substr .
  6. Puede agregar otras columnas de su conjunto de datos (t.name, t.project como ejemplo) para una fácil visualización.

Algunas referencias a documentos de Oracle:

  • REGEXP_REPLACE
  • REGEXP_SUBSTR
  • Constantes de extensibilidad, tipos y asignaciones (OdciNumberList)
  • CAST (conjunto múltiple)
  • Consultas jerárquicas