Ако разбирам добре, не е нужно просто да замените „,“ с интервал, но и да премахнете дубликати по по-интелигентен начин.
Ако модифицирам този израз, за да работи с интервал вместо ',', получавам
select regexp_replace('A B A A C D' ,'([^ ]+)( [ ]*\1)+', '\1') from dual
което дава 'A B A C D'
, не това, от което се нуждаете.
Начинът да получите желания резултат може да бъде следният, малко по-сложен:
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
)
)
Основният ми проблем тук е, че не мога да създам регулярно изразно изражение, което проверява за несъседни дубликати, така че трябва да разделя низа, да проверя за дубликати и след това отново да събера недублираните стойности, като запазя реда.
Ако нямате нищо против реда на токените в резултантния низ, това може да се опрости:
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
)