복붙노트

[SQL] 어떻게 오라클 REGEXP_REPLACE에 의해 공간이 구분 된 목록에서 중복을 제거하는 방법? [복제]

SQL

어떻게 오라클 REGEXP_REPLACE에 의해 공간이 구분 된 목록에서 중복을 제거하는 방법? [복제]

나는 'A B A A C D'라는 목록을 가지고있다. 내 예상 결과는 'A B C D'입니다. 지금까지 웹에서 내가 발견 한

regexp_replace(l_user ,'([^,]+)(,[ ]*\1)+', '\1');

표현. 그러나 이것은, 구분 된 목록입니다. 이 공간이 구분 된 목록 만들기 위해 할 수있는 수정의 필요가 무엇입니까. 어떤 순서를 고려해야합니다.

해결법

  1. ==============================

    1.내가 잘 이해한다면 당신은 단순히 공간 ','교체 할 필요가 없습니다뿐만 아니라 똑똑한 방법으로 중복을 제거 할 수 있습니다.

    내가 잘 이해한다면 당신은 단순히 공간 ','교체 할 필요가 없습니다뿐만 아니라 똑똑한 방법으로 중복을 제거 할 수 있습니다.

    내가 대신의 공간 ','와 일에 그 표현을 수정하는 경우, 내가 얻을

    select regexp_replace('A B A A C D' ,'([^ ]+)( [ ]*\1)+', '\1') from dual
    

    이는 'A B A C D'를 제공, 당신은 필요가 없습니다 것.

    당신의 필요한 결과를 얻을 수있는 방법은 다음, 더 복잡 조금 될 수있다 :

    with string(s) as ( select 'A B A A C D' from dual)    
        select listagg(case when rn = 1 then str end, ' ') within group (order by lev)
        from (
                select str,  row_number() over (partition by str order by 1) rn, lev
                from (
                    SELECT trim(regexp_substr(s, '[^ ]+', 1, level)) str,
                           level as lev
                      FROM string
                    CONNECT BY instr(s, ' ', 1, level - 1) > 0
                    )
             )
    

    여기 내 주요 문제는이 정규 표현식을 구축 할 수 아니에요입니다 내가 순서를 유지하고 집계 다시 비 중복 값을 중복의 캐릭터, 수표를 분할 할 필요가 인접하지 않은 중복을 검사, 그래서.

    당신은 결과 문자열에서 토큰의 순서를 신경 쓰지 않는 경우,이 단순화 될 수있다 :

    with string(s) as ( select 'A B A A C D' from dual)
    select listagg(str, ' ') within group (order by 1)
    from (
            SELECT distinct trim(regexp_substr(s, '[^ ]+', 1, level)) as str
              FROM string
            CONNECT BY instr(s, ' ', 1, level - 1) > 0
         )
    
  2. ==============================

    2.문제가 더 복잡하기 때문에, - 당신은 (같은 결과에 모두 리드 때문에 예는 가난,이 점에서 선택 알파벳순으로 재정렬, 말,하지) 자신의 첫 번째 항목의 순서로 구성 요소 문자열을 유지하려는 가정 당신은 순서를 추적도 유지해야합니다. ROW_NUMBER ()가 도움이 어디 여기 - 그럼 각 문자에 대해 당신은 단지 첫 번째 항목을 유지해야합니다.

    문제가 더 복잡하기 때문에, - 당신은 (같은 결과에 모두 리드 때문에 예는 가난,이 점에서 선택 알파벳순으로 재정렬, 말,하지) 자신의 첫 번째 항목의 순서로 구성 요소 문자열을 유지하려는 가정 당신은 순서를 추적도 유지해야합니다. ROW_NUMBER ()가 도움이 어디 여기 - 그럼 각 문자에 대해 당신은 단지 첫 번째 항목을 유지해야합니다.

    with
         inputs ( str ) as ( select 'A B A A C D' from dual)
    -- end test data; solution begins below this line
    select listagg(token, ' ') within group (order by id) as new_str
    from (
           select level as id, regexp_substr(str, '[^ ]+', 1, level) as token,
                  row_number() over ( 
                                 partition by regexp_substr(str, '[^ ]+', 1, level)
                                 order by level ) as rn
    
           from   inputs
           connect by regexp_substr(str, '[^ ]+', 1, level) is not null
         )
    where rn = 1
    ;
    
  3. ==============================

    3.XQuery를?

    XQuery를?

    select xmlquery('string-join(distinct-values(ora:tokenize(.," ")), " ")' passing  'A B A A C D' returning content) result  from dual
    
  4. from https://stackoverflow.com/questions/40259200/how-to-remove-duplicates-from-space-separated-list-by-oracle-regexp-replace by cc-by-sa and MIT license