Berikut cara mengatasi masalah Anda.
select
regexp_replace(
'2,2,2.1,3,3,3,3,4,4'
,'([^,]+)(,\1)*(,|$)', '\1\3')
from dual
kembali
2,2.1,3,4
Dari oracle 19C dibangun lihat di sini
Dari 18C dan sebelumnya coba dalam lihat kelompok di sini
Jika tidak, gunakan ekspresi reguler
JAWABAN di bawah ini:
select col1,
regexp_replace(
listagg(
col2 , ',') within group (order by col2) -- sorted
,'([^,]+)(,\1)*(,|$)', '\1\3') )
from tableX
where rn = 1
group by col1;
Catatan: Cara di atas akan berfungsi dalam banyak kasus - daftar harus diurutkan, Anda mungkin harus memangkas semua spasi di belakang dan di depan tergantung pada data Anda.
Jika Anda memiliki banyak item dalam grup> 20 atau ukuran string besar Anda mungkin mengalami batas ukuran string oracle 'hasil rangkaian string terlalu panjang'.
Dari oracle 12cR2 Anda dapat menekan kesalahan ini, lihat di sini . Atau berikan jumlah maksimal pada anggota di setiap grup. Ini hanya akan berfungsi jika tidak masalah untuk mencantumkan hanya anggota pertama. Jika Anda memiliki string variabel yang sangat panjang, ini mungkin tidak berfungsi. Anda harus bereksperimen.
select col1,
case
when count(col2) < 100 then
regexp_replace(
listagg(col2, ',') within group (order by col2)
,'([^,]+)(,\1)*(,|$)', '\1\3')
else
'Too many entries to list...'
end
from sometable
where rn = 1
group by col1;
Solusi lain (tidak sesederhana itu) untuk menghindari batas ukuran string oracle - ukuran string dibatasi hingga 4000. Terima kasih untuk posting ini di sini oleh user3465996
select col1 ,
dbms_xmlgen.convert( -- HTML decode
dbms_lob.substr( -- limit size to 4000 chars
ltrim( -- remove leading commas
REGEXP_REPLACE(REPLACE(
REPLACE(
XMLAGG(
XMLELEMENT("A",col2 )
ORDER BY col2).getClobVal(),
'<A>',','),
'</A>',''),'([^,]+)(,\1)*(,|$)', '\1\3'),
','), -- remove leading XML commas ltrim
4000,1) -- limit to 4000 string size
, 1) -- HTML.decode
as col2
from sometable
where rn = 1
group by col1;
V1 - beberapa kasus uji - FYI
regexp_replace('2,2,2.1,3,3,4,4','([^,]+)(,\1)+', '\1')
-> 2.1,3,4 Fail
regexp_replace('2 ,2 ,2.1,3 ,3 ,4 ,4 ','([^,]+)(,\1)+', '\1')
-> 2 ,2.1,3,4 Success - fixed length items
V2 -item yang terkandung dalam item mis. 2,21
regexp_replace('2.1,1','([^,]+)(,\1)+', '\1')
-> 2.1 Fail
regexp_replace('2 ,2 ,2.1,1 ,3 ,4 ,4 ','(^|,)(.+)(,\2)+', '\1\2')
-> 2 ,2.1,1 ,3 ,4 -- success - NEW regex
regexp_replace('a,b,b,b,b,c','(^|,)(.+)(,\2)+', '\1\2')
-> a,b,b,c fail!
v3 - regex terima kasih Igor! bekerja di semua kasus.
select
regexp_replace('2,2,2.1,3,3,4,4','([^,]+)(,\1)*(,|$)', '\1\3') ,
---> 2,2.1,3,4 works
regexp_replace('2.1,1','([^,]+)(,\1)*(,|$)', '\1\3'),
--> 2.1,1 works
regexp_replace('a,b,b,b,b,c','([^,]+)(,\1)*(,|$)', '\1\3')
---> a,b,c works
from dual