Jeśli dobrze rozumiem, nie musisz po prostu zastępować „,” spacją, ale także usuwać duplikaty w inteligentniejszy sposób.
Jeśli zmodyfikuję to wyrażenie, aby działało ze spacją zamiast ',', otrzymam
select regexp_replace('A B A A C D' ,'([^ ]+)( [ ]*\1)+', '\1') from dual
co daje 'A B A C D'
, a nie to, czego potrzebujesz.
Sposób na uzyskanie pożądanego wyniku może być następujący, nieco bardziej skomplikowany:
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
)
)
Moim głównym problemem jest to, że nie jestem w stanie zbudować wyrażenia regularnego, które sprawdza, czy nie są sąsiadujące z duplikatami, więc muszę podzielić ciąg, sprawdzić duplikaty, a następnie ponownie zagregować niezduplikowane wartości, zachowując kolejność.
Jeśli nie masz nic przeciwko kolejności tokenów w ciągu wynikowym, można to uprościć:
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
)