Đây là một giải pháp chỉ sử dụng các hàm chuỗi tiêu chuẩn (thay vì các biểu thức chính quy) - điều này sẽ dẫn đến việc thực thi nhanh hơn trong hầu hết các trường hợp; nó chỉ loại bỏ 3 khi nó là ký tự đầu tiên được theo sau bởi dấu phẩy, ký tự cuối cùng đứng trước dấu phẩy hoặc đứng trước và theo sau bởi dấu phẩy và nó loại bỏ dấu phẩy đứng trước nó trong trường hợp giữa và nó loại bỏ dấu phẩy theo sau nó trong trường hợp thứ nhất và thứ ba.
Nó có thể loại bỏ hai số 3 liên tiếp (điều mà một số giải pháp khác được cung cấp không thể làm được) trong khi để lại dấu phẩy liên tiếp (có lẽ là viết tắt của NULL) và không làm phiền các số như 38 hoặc 123.
Chiến lược đầu tiên là nhân đôi mọi dấu phẩy (thay thế ,
với ,,
) và thêm và thêm dấu phẩy (vào đầu và cuối chuỗi). Sau đó, loại bỏ mọi sự xuất hiện của ,3,
. Từ những gì còn lại, thay thế mọi ,,
quay lại với một ,
và cuối cùng xóa ,
đầu và cuối .
with
test_data ( str ) as (
select '1,2,3,4,5' from dual union all
select '1,2,3,3,4,4,5' from dual union all
select '12,34,5' from dual union all
select '1,,,3,3,3,4' from dual
)
select str,
trim(both ',' from
replace( replace(',' || replace(str, ',', ',,') || ',', ',3,'), ',,', ',')
) as new_str
from test_data
;
STR NEW_STR
------------- ----------
1,2,3,4,5 1,2,4,5
1,2,3,3,4,4,5 1,2,4,4,5
12,34,5 12,34,5
1,,,3,3,3,4 1,,,4
4 rows selected.
Lưu ý Như đã chỉ ra bởi MT0 (xem Nhận xét bên dưới), điều này sẽ cắt quá nhiều nếu chuỗi gốc bắt đầu hoặc kết thúc bằng dấu phẩy. Để bao gồm trường hợp đó, thay vì gói mọi thứ trong trim(both ',' from ...)
Tôi nên gói phần còn lại trong một truy vấn con và sử dụng một cái gì đó như substr(new_str, 2, length(new_str) - 2)
trong truy vấn bên ngoài.