วิธีแก้ปัญหาของคุณมีดังนี้
select
regexp_replace(
'2,2,2.1,3,3,3,3,4,4'
,'([^,]+)(,\1)*(,|$)', '\1\3')
from dual
ผลตอบแทน
2,2.1,3,4
จาก oracle 19C สร้างขึ้นในดูที่นี่
จาก 18C และก่อนหน้านี้ลองภายในกลุ่มดูที่นี่
หรือใช้นิพจน์ทั่วไป
คำตอบด้านล่าง:
select col1,
regexp_replace(
listagg(
col2 , ',') within group (order by col2)
,'([^,]+)(,\1)*(,|$)', '\1\3') )
from tableX
where rn = 1
group by col1;
หมายเหตุ: ข้างต้นจะใช้งานได้ในกรณีส่วนใหญ่ - รายการควรเรียงลำดับคุณอาจต้องตัดแต่งช่องว่างต่อท้ายและนำหน้าทั้งหมดขึ้นอยู่กับข้อมูลของคุณ
หากคุณมีรายการจำนวนมากในกลุ่ม> 20 หรือขนาดสตริงที่ใหญ่คุณอาจพบกับขีด จำกัด ขนาดสตริง oracle 'ผลลัพธ์ของการต่อสตริงยาวเกินไป'
จาก Oracle 12cR2 คุณสามารถระงับข้อผิดพลาดนี้ดูที่นี่ หรือใส่จำนวนสูงสุดให้กับสมาชิกในแต่ละกลุ่ม สิ่งนี้จะใช้ได้ก็ต่อเมื่อสามารถแสดงเฉพาะสมาชิกคนแรก หากคุณมีสตริงตัวแปรที่ยาวมากสิ่งนี้อาจใช้ไม่ได้ คุณจะต้องทดลอง
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;
อีกวิธีหนึ่ง (ไม่ง่ายนัก) เพื่อหลีกเลี่ยงการ จำกัด ขนาดสตริง oracle - ขนาดสตริง จำกัด ไว้ที่ 4000 ขอบคุณโพสต์นี้ที่นี่โดยuser3465996
select col1 ,
dbms_xmlgen.convert(
dbms_lob.substr(
ltrim(
REGEXP_REPLACE(REPLACE(
REPLACE(
XMLAGG(
XMLELEMENT("A",col2 )
ORDER BY col2).getClobVal(),
'<A>',','),
'</A>',''),'([^,]+)(,\1)*(,|$)', '\1\3'),
','),
4000,1)
, 1)
as col2
from sometable
where rn = 1
group by col1;
V1 - กรณีทดสอบบางส่วน - 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 - รายการที่มีอยู่ในรายการเช่น 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
regexp_replace('a,b,b,b,b,c','(^|,)(.+)(,\2)+', '\1\2')
-> a,b,b,c fail!
v3 - regex ขอบคุณอิกอร์! ใช้ได้กับทุกกรณี
select
regexp_replace('2,2,2.1,3,3,4,4','([^,]+)(,\1)*(,|$)', '\1\3') ,
regexp_replace('2.1,1','([^,]+)(,\1)*(,|$)', '\1\3'),
regexp_replace('a,b,b,b,b,c','([^,]+)(,\1)*(,|$)', '\1\3')
from dual