So lösen Sie Ihr Problem.
select
regexp_replace(
'2,2,2.1,3,3,3,3,4,4'
,'([^,]+)(,\1)*(,|$)', '\1\3')
from dual
kehrt zurück
2,2.1,3,4
Vom Orakel 19C wird in See gebaut hier
Ab 18C und früher versuchen Sie es innerhalb der Gruppe hier
Verwenden Sie andernfalls reguläre Ausdrücke
ANTWORT unten:
select col1,
regexp_replace(
listagg(
col2 , ',') within group (order by col2) -- sorted
,'([^,]+)(,\1)*(,|$)', '\1\3') )
from tableX
where rn = 1
group by col1;
Hinweis: Die oben genannten Funktionen funktionieren in den meisten Fällen. Die Liste sollte sortiert sein. Abhängig von Ihren Daten müssen Sie möglicherweise den gesamten nachfolgenden und führenden Speicherplatz kürzen.
Wenn Sie eine Vielzahl von Elementen in einer Gruppe> 20 oder großen Zeichenfolgen haben, kann es vorkommen, dass die Größe der Oracle-Zeichenfolge auf "Ergebnis der Verkettung von Zeichenfolgen zu lang" begrenzt ist.
Ab Oracle 12cR2 können Sie diesen Fehler unterdrücken, siehe hier . Alternativ können Sie den Mitgliedern in jeder Gruppe eine maximale Anzahl hinzufügen. Dies funktioniert nur, wenn es in Ordnung ist, nur die ersten Mitglieder aufzulisten. Wenn Sie sehr lange variable Zeichenfolgen haben, funktioniert dies möglicherweise nicht. Sie müssen experimentieren.
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;
Eine andere Lösung (nicht so einfach), um hoffentlich die Beschränkung der Orakel- Stringgröße zu vermeiden - die String-Größe ist auf 4000 begrenzt. Dank dieses Beitrags hier von 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 - einige Testfälle - 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-Elemente, die in Elementen enthalten sind, z. 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 danke Igor! funktioniert in allen Fällen.
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