문제를 해결하는 방법은 다음과 같습니다.
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) -- sorted
,'([^,]+)(,\1)*(,|$)', '\1\3') )
from tableX
where rn = 1
group by col1;
참고 : 위의 내용은 대부분의 경우 작동합니다. 목록을 정렬해야하며 데이터에 따라 모든 후행 및 선행 공백을 잘라야 할 수 있습니다.
그룹에 20 개 이상의 문자열 크기 또는 큰 문자열 크기의 항목이 많은 경우 '문자열 연결 결과가 너무 깁니다'라는 오라클 문자열 크기 제한에 부딪 힐 수 있습니다.
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;
(그렇게 간단하지) 또 다른 해결책은 희망 오라클 문자열 크기 제한을 피하기 위해 - 문자열 크기가이 게시물에 4000 감사로 제한됩니다 여기 에서 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-일부 테스트 사례-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 -- success - NEW regex
regexp_replace('a,b,b,b,b,c','(^|,)(.+)(,\2)+', '\1\2')
-> a,b,b,c fail!
v3-정규식 Igor 감사합니다! 모든 경우에 작동합니다.
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