Oto jak rozwiązać problem.
select
regexp_replace(
'2,2,2.1,3,3,3,3,4,4'
,'([^,]+)(,\1)*(,|$)', '\1\3')
from dual
zwroty
2,2.1,3,4
Od Oracle 19C jest zbudowany w patrz tutaj
Od 18 ° C i wcześniej spróbuj w grupie, patrz tutaj
W przeciwnym razie użyj wyrażeń regularnych
Odpowiedź poniżej:
select col1,
regexp_replace(
listagg(
col2 , ',') within group (order by col2)
,'([^,]+)(,\1)*(,|$)', '\1\3') )
from tableX
where rn = 1
group by col1;
Uwaga: powyższe zadziała w większości przypadków - lista powinna być posortowana, może być konieczne przycięcie całej końcowej i początkowej spacji w zależności od danych.
Jeśli masz dużo elementów w grupie> 20 lub duże ciągi znaków, możesz napotkać limit rozmiaru łańcucha Oracle „wynik konkatenacji ciągów jest za długi”.
Z Oracle 12cR2 możesz pominąć ten błąd, patrz tutaj . Ewentualnie podaj maksymalną liczbę członków w każdej grupie. To zadziała tylko wtedy, gdy możesz podać tylko pierwszych członków. Jeśli masz bardzo długie ciągi zmiennych, może to nie działać. będziesz musiał eksperymentować.
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;
Innym rozwiązaniem (nie takie proste), aby uniknąć nadzieją oracle limit rozmiaru String - Ciąg wielkość jest ograniczona do 4000. Dzięki tym poście tutaj przez 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 - kilka przypadków testowych - 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 - pozycje zawarte w pozycjach np. 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 dzięki Igorowi! działa we wszystkich przypadkach.
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