Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Dividindo string em várias linhas no Oracle


Esta pode ser uma maneira aprimorada (também com regexp e conectar por):
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 :Aqui está uma explicação simples (como em "não em profundidade") da consulta.
  1. length (regexp_replace(t.error, '[^,]+')) + 1 usa regexp_replace para apagar qualquer coisa que não seja o delimitador (vírgula neste caso) e length +1 para obter quantos elementos (erros) existem.

  2. O select level from dual connect by level <= (...) usa uma consulta hierárquica para criar uma coluna com um número crescente de correspondências encontradas, de 1 ao número total de erros.

    Visualização:
    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)) faz alguns lançamentos de tipos de oráculos.
    • O cast(multiset(.....)) as sys.OdciNumberList transforma várias coleções (uma coleção para cada linha no conjunto de dados original) em uma única coleção de números, OdciNumberList.
    • A table() função transforma uma coleção em um conjunto de resultados.

  4. FROM sem uma junção cria uma junção cruzada entre seu conjunto de dados e o multiconjunto. Como resultado, uma linha no conjunto de dados com 4 correspondências será repetida 4 vezes (com um número crescente na coluna denominada "valor_coluna").

    Visualização:
    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 o column_value como a nth_appearance/ocurrence parâmetro para regexp_substr .
  6. Você pode adicionar algumas outras colunas do seu conjunto de dados (t.name, t.project como exemplo) para facilitar a visualização.

Algumas referências a documentos Oracle:
  • REGEXP_REPLACE
  • REGEXP_SUBSTR
  • Constantes, tipos e mapeamentos de extensibilidade (OdciNumberList)
  • CAST (multiconjunto)
  • Consultas hierárquicas