Jika saya memahaminya dengan baik, Anda tidak hanya perlu mengganti ',' dengan spasi, tetapi juga menghapus duplikat dengan cara yang lebih cerdas.
Jika saya memodifikasi ekspresi itu agar berfungsi dengan spasi alih-alih ',', saya mendapatkan
select regexp_replace('A B A A C D' ,'([^ ]+)( [ ]*\1)+', '\1') from dual
yang memberikan 'A B A C D'
, bukan yang Anda butuhkan.
Cara untuk mendapatkan hasil yang Anda butuhkan adalah sebagai berikut, sedikit lebih rumit:
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
)
)
Masalah utama saya di sini adalah bahwa saya tidak dapat membuat regexp yang memeriksa duplikat yang tidak berdekatan, jadi saya perlu membagi string, memeriksa duplikat dan kemudian menggabungkan lagi nilai yang tidak digandakan, menjaga urutannya.
Jika Anda tidak keberatan dengan urutan token dalam string hasil, ini dapat disederhanakan:
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
)