Как удалить дублированные значения из атрибута - PullRequest
0 голосов
/ 05 июля 2019

У меня есть столбец с дублированными значениями в одной ячейке, скажите, пожалуйста, как я могу удалить дублированные значения, используя только sql или pl / sql.

 | Test
-+--------------------------------------------------------------------
 | 999999999(10145) 999999999(10145) 999999999(10145) 999999999(10145)
 |--------------------------------------------------------------------
 | 113307425(2) 310122174(2) 310122174(2) 113307425(2)

Ответы [ 2 ]

2 голосов
/ 05 июля 2019

Используйте регулярное выражение с обратной ссылкой, чтобы соответствовать повторяющимся терминам:

Установка Oracle :

CREATE TABLE test_data ( value ) AS
SELECT '9999999(12345) 9999999(12345) 9999999(12345) 9999999(12345)' FROM DUAL;

Запрос

SELECT REGEXP_REPLACE( value, '([^ ]+)( \1)+', '\1' ) AS replaced_value
FROM   test_data

выход

| REPLACED_VALUE |
| :------------- |
| 9999999(12345) |

дБ <> скрипка здесь


Обновлено : Для новых данных в 6-м редактировании:

CREATE TABLE test_data ( value ) AS
SELECT '9999999(12345) 9999999(12345) 9999999(12345) 9999999(12345)' FROM DUAL UNION ALL
SELECT '113307425(2) 310122174(2) 310122174(2) 113307425(2)' FROM DUAL;

Запрос

Используйте рекурсивное условие факторинга подзапроса, чтобы найти термины в строке, а затем используйте DISTINCT, чтобы удалить дубликаты, и LISTAGG, чтобы объединить их обратно в одну строку.

WITH bounds ( id, value, start_pos, end_pos ) AS (
  SELECT ROWID,
         value,
         1,
         INSTR( value, ' ', 1 )
  FROM   test_data
UNION ALL
  SELECT id,
         value,
         end_pos + 1,
         INSTR( value, ' ', end_pos + 1 )
  FROM   bounds
  WHERE  end_pos > 0
),
strings ( id, value ) AS (
  SELECT DISTINCT
         id,
         CASE end_pos
           WHEN 0
           THEN SUBSTR( value, start_pos )
           ELSE SUBSTR( value, start_pos, end_pos - start_pos )
         END
  FROM   bounds
)
SELECT LISTAGG( value, ' ' ) WITHIN GROUP ( ORDER BY value ) AS unique_values
FROM   strings
GROUP BY id

выход

| UNIQUE_VALUES             |
| :------------------------ |
| 9999999(12345)            |
| 113307425(2) 310122174(2) |

дБ <> скрипка здесь

0 голосов
/ 05 июля 2019

Oracle допускает рекурсивный факторинг подзапросов, который можно использовать для многократного применения подстановок на основе регулярных выражений:

CREATE TABLE test_data ( value ) AS
SELECT '9999999(12345) 9999999(12345) 9999999(12345) 9999999(12345)' FROM DUAL;

WITH rep(n,s,n_maxrep) AS (
    SELECT 1
         , value
         , 1 + LENGTH(REGEXP_REPLACE(value, '[^ ]', ''))
      FROM test_data
 UNION ALL
    SELECT n+1
         , REGEXP_REPLACE ( s, '([^ ]+)(( [^ ]+)*)( \1)+', '\1\2' ) 
         , n_maxrep
      FROM rep
     WHERE n <= n_maxrep
)
SELECT s FROM rep WHERE n = n_maxrep;

Объяснение

В запросе неоднократно применяется одна и та же базовая замена на основе регулярных выражений одного дубликата глагола. в исходный столбец. «Глагол» в этом контексте - это максимальная последовательность последовательных непробельных символов. Дубликаты могут быть рядом друг с другом или разделяться другими глаголами.

Максимально возможное количество таких замен известно заранее: n-1 для n глаголов, когда все глаголы идентичны. Это эквивалентно количеству появлений разделяющего символа в исходном значении.

Все остальное - синтаксический сахар. Oracle строит вложенную цепочку подзапросов самостоятельно.

Обратите внимание, что предел n_maxrep фактически равен 1 + . Это необходимо, так как базовый вариант (n=1) не заменяет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...