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

Come rimuovere i duplicati dall'elenco separato da spazi da Oracle regexp_replace?

Se ho capito bene non devi semplicemente sostituire ',' con uno spazio, ma anche rimuovere i duplicati in modo più intelligente.

Se modifico quell'espressione per lavorare con lo spazio invece di ',', ottengo

select regexp_replace('A B A A C D' ,'([^ ]+)( [ ]*\1)+', '\1') from dual

che dà 'A B A C D' , non quello che ti serve.

Un modo per ottenere il risultato desiderato potrebbe essere il seguente, un po' più complicato:

with string(s) as ( select 'A B A A C D' from dual)    
    select listagg(case when rn = 1 then str end, ' ') within group (order by lev)
    from (
            select str,  row_number() over (partition by str order by 1) rn, lev
            from (
                SELECT trim(regexp_substr(s, '[^ ]+', 1, level)) str,
                       level as lev
                  FROM string
                CONNECT BY instr(s, ' ', 1, level - 1) > 0
                )
         )

Il mio problema principale qui è che non sono in grado di creare un'espressione regolare che controlli i duplicati non adiacenti, quindi devo dividere la stringa, verificare la presenza di duplicati e quindi aggregare nuovamente i valori non duplicati, mantenendo l'ordine.

Se non ti dispiace l'ordine dei token nella stringa dei risultati, questo può essere semplificato:

with string(s) as ( select 'A B A A C D' from dual)
select listagg(str, ' ') within group (order by 1)
from (
        SELECT distinct trim(regexp_substr(s, '[^ ]+', 1, level)) as str
          FROM string
        CONNECT BY instr(s, ' ', 1, level - 1) > 0
     )