sql >> Databáze >  >> RDS >> Oracle

Jak odstranit duplikáty ze seznamu odděleného mezerou pomocí Oracle regexp_replace?

Pokud tomu dobře rozumím, nemusíte jednoduše nahradit ',' mezerou, ale také odstranit duplikáty chytřeji.

Pokud tento výraz upravím tak, aby pracoval s mezerou místo ',', dostanu

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

což dává 'A B A C D' , ne to, co potřebujete.

Způsob, jak dosáhnout požadovaného výsledku, může být následující, o něco složitější:

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

Můj hlavní problém je, že nejsem schopen vytvořit regexp, který kontroluje nesousedící duplikáty, takže musím rozdělit řetězec, zkontrolovat duplikáty a pak znovu agregovat neduplikované hodnoty, přičemž dodržím pořadí.

Pokud vám nevadí pořadí tokenů ve výsledném řetězci, lze to zjednodušit:

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. Oracle - Proč zmizí úvodní nula čísla při převodu na TO_CHAR

  2. Pomocí průvodce Offline reorganizací

  3. Jakou funkci maskování dat bych měl použít?

  4. Jak získat čas z řetězce v MySQL