Nếu tôi hiểu rõ, bạn không chỉ cần thay thế ',' bằng một khoảng trắng mà còn phải xóa các bản sao theo cách thông minh hơn.
Nếu tôi sửa đổi biểu thức đó để hoạt động với khoảng trắng thay vì ',', tôi nhận được
select regexp_replace('A B A A C D' ,'([^ ]+)( [ ]*\1)+', '\1') from dual
mang lại cho 'A B A C D'
, không phải những gì bạn cần.
Một cách để có được kết quả cần thiết của bạn có thể là như sau, phức tạp hơn một chút:
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
)
)
Vấn đề chính của tôi ở đây là tôi không thể tạo regexp để kiểm tra các bản sao không liền kề, vì vậy, tôi cần phải tách chuỗi, kiểm tra các bản sao và sau đó tổng hợp lại các giá trị không trùng lặp, giữ nguyên thứ tự.
Nếu bạn không bận tâm về thứ tự của các mã trong chuỗi kết quả, điều này có thể được đơn giản hóa:
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
)