sql >> Database >  >> RDS >> Oracle

Hoe duplicaten te verwijderen uit een door de ruimte gescheiden lijst door Oracle regexp_replace?

Als ik het goed begrijp hoef je niet alleen ',' te vervangen door een spatie, maar ook om duplicaten op een slimmere manier te verwijderen.

Als ik die uitdrukking aanpas om met spatie te werken in plaats van ',', krijg ik

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

wat 'A B A C D' . geeft , niet wat je nodig hebt.

Een manier om het gewenste resultaat te krijgen kan de volgende zijn, een beetje ingewikkelder:

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
                )
         )

Mijn grootste probleem hier is dat ik geen regexp kan bouwen die controleert op niet-aangrenzende duplicaten, dus ik moet de string splitsen, controleren op duplicaten en dan de niet-gedupliceerde waarden opnieuw aggregeren, waarbij de volgorde behouden blijft.

Als u de volgorde van de tokens in de resultaatreeks niet erg vindt, kan dit worden vereenvoudigd:

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
     )


  1. Kan pg gem niet installeren op Mountain Lion

  2. ORA-01036:ongeldige variabele naam/nummer bij het uitvoeren van een query via C#

  3. Hoe te voorkomen dat de SSIS FTP-taak mislukt als er geen bestanden zijn om te downloaden?

  4. Wat is eigenlijk een hoofdversie?