Вопрос:
Мне нужна ваша помощь с функцией regexp_replace. У меня есть таблица, которая имеет столбец для связанных значений строки, которые содержат дубликаты. Как я могу их устранить?
Пример:
Ian,Beatty,Larry,Neesha,Beatty,Neesha,Ian,Neesha
Мне нужен вывод
Ian,Beatty,Larry,Neesha
Дубликаты являются случайными, а не в каком-либо определенном порядке.
Update–
Вот как выглядит мой стол
ID Name1 Name2 Name3 1 a b c 1 c d a 2 d e a 2 c d b
Мне нужна одна строка для каждого идентификатора, имеющего разные имена1, name2, name3 в одной строке в виде строки, разделенной запятой.
ID Name 1 a,c,b,d,c 2 d,c,e,a,b
Я пробовал использовать listagg с четкими, но я не могу удалить дубликаты.
Ответ №1
Итак, попробуйте это…
([^,]+),(?=.*[A-Za-z],[] ]*1) Ответ №2
Я не думаю, что вы можете сделать это только с помощью regexp_replace если повторяющиеся значения не находятся рядом друг с другом. Один из подходов состоит в том, чтобы разбить значения, устранить дубликаты, а затем вернуть их обратно.
Общий метод tokenize строки с разделителями – с regexp_substr и предложением connect by. Использование переменной привязки с вашей строкой, чтобы сделать код более понятным:
var value varchar2(100); exec :value := ‘Ian,Beatty,Larry,Neesha,Beatty,Neesha,Ian,Neesha’; select regexp_substr(:value, ‘[^,]+’, 1, level) as value from dual connect by regexp_substr(:value, ‘[^,]+’, 1, level) is not null; VALUE —————————— Ian Beatty Larry Neesha Beatty Neesha Ian Neesha
Вы можете использовать это как подзапрос (или CTE), получить от него различные значения, а затем собрать его с помощью listagg:
select listagg(value, ‘,’) within group (order by value) as value from ( select distinct value from ( select regexp_substr(:value, ‘[^,]+’, 1, level) as value from dual connect by regexp_substr(:value, ‘[^,]+’, 1, level) is not null ) ); VALUE —————————— Beatty,Ian,Larry,Neesha
Это немного сложнее, если вы смотрите на несколько строк в таблице, так как это путает синтаксис соединения, но вы можете использовать неопределяющую ссылку, чтобы избежать циклов:
with t42 (id, value) as ( select 1, ‘Ian,Beatty,Larry,Neesha,Beatty,Neesha,Ian,Neesha’ from dual union all select 2, ‘Mary,Joe,Mary,Frank,Joe’ from dual ) select id, listagg(value, ‘,’) within group (order by value) as value from ( select distinct id, value from ( select id, regexp_substr(value, ‘[^,]+’, 1, level) as value from t42 connect by regexp_substr(value, ‘[^,]+’, 1, level) is not null and id = prior id and prior dbms_random.value is not null ) ) group by id; ID VALUE ———- —————————— 1 Beatty,Ian,Larry,Neesha 2 Frank,Joe,Mary
Конечно, это не обязательно, если вы правильно храните реляционные данные; наличие разделительной строки в столбце не является хорошей идеей.