Удалить повторяющиеся символы в строке oracle

Обновлено: 07.07.2024

В посте рассматриваются однострочные функции SUBSTR и INSTR, работающие с символьными данными.

Символьные данные или строки являются универсальными, т.к. они позволяют хранить практически любой тип данных. Функции, которые работают с символьными данными, классифицируются на функции преобразования регистра символов и манипулирования символами.

Функции манипулирования символами используются для извлечения, преобразования и форматирования символьных строк. К этому классу относятся функции CONCAT, LENGTH, LPAD, RPAD, TRIM, REPLACE и рассматриваемые нижу функции SUBSTR и INSTR.

Функция SUBSTR принимает три параметра и возвращает строку, состоящую из количества символов, извлеченных из исходной строки, начиная с указанной начальной позиции:

SUBSTR (строка, начальная позиция, количество символов).

В приведенном примере извлекаются символы с первой по четвертую позиции из значений колонки last_name. Для сравнения выводятся исходные значения колонки last_name.


Функция INSTR возвращает число, представляющее позицию в исходной строке, начиная с заданной начальной позиции, где n-ное вхождение элемента поиска начинается:

INSTR (строка, элемент поиска, [начальная позиция], [n-ное вхождение элемента поиска]

Следующий запрос показывает позицию строчной буквы a для каждой строки колонки last_name. Если в строке встречаются два или более символов a, то будет отображена позиция первого/начального из них. Для сравнения и анализа выводятся исходные значения колонки.


Если необходимо также отобразить позицию заглавной буквы А в фамилии, то надо предварительно перевести все символы фамилии в строчные, используя вложенную функцию LOWER. Запрос выглядит следующим образом:


Как видно из результата, теперь позиция заглавной буквы A тоже определяется, например, для Abel, Ande, Atkinson, Austin возвращается значение 1.

В посте приведен пример совместного применения таких функций, как LENGTH, SUBSTR и INSTR.

Повторяющиеся символы
Добрый вечер! Помогите пожалуйста дорешать задачу , суть задачи такова:Дан тестовый файл , нужно.

Повторяющиеся символы в строке
Дано слово. Удалить из него все повторяющиеся буквы, оставив их первые вхождения, то есть в слове.

Повторяющиеся символы в строке
Здравствуйте, есть вопросик. Мне нужно проверить, есть ли в строке одинаковые подряд идущие символы.

'%Иванов%' не устраивает тем, что % - это любое количество любых символов.

Добавлено через 20 минут
Почитал про ltrim и rtrim.
Не пойму, как присобачить это в запрос. То есть чтоб одновременно оба трима срабатывали в поле Фамилия и при этом это еще и сравнивалось в блоке WHERE с 'Иванов'. Какая-то ерунда

Решение

Вопрос iap я, к сожалению, не понял.
Ice_and_Fire, спасибо, я затупил конкретно
Мне подходит SELECT . WHERE LTRIM(RTRIM(LastName)) LIKE 'Иванов'.
Всем спасибо. Это очень сложный вопрос!
В таблице может быть много строк. Вы знали? Нет, спасибо, что рассказали
Возможно, в Вашем вопросе скрыт глубокий философский смысл, однако я не могу представить ситуацию, когда в таблице, предназначенной для хранения информации о людях, будут "Все Ивановы - на одной строке". А ничего, что LIKE 'Иванов' - это то же самое, что и = 'Иванов' ?
В начальном тексте говорится о ФИО. А на самом деле там только фамилия?
Как отличить фамилию от имени? Иванович - может быть и то и другое.
Кстати, LIKE 'Иванов%' и Ивановича, и Иванову тоже выдаст.
Так что лучше формулируйте задачу. Фамилия дана как пример, чтобы не загромождать тему лишним кодом. Разговор как велся, так и ведется о ФИО целиком.
Речь о строке, в которой имя, фамилия и отчество находятся в разных полях. Если я не объяснил этого доступно, приношу свои извинения.

Повторяющиеся символы в строке
Разработать программу, которая вводит текст, заменяет в нем стоящие подряд одинаковые символы одним.


Удалить повторяющиеся символы
Вывести текстовую строку без повторяющихся символов. Подскажите пожалуйста, в чем ошибка.


Повторяющиеся символы в строке
Суть задачи: Написать функцию, которая находит в строке, переданной в качестве аргумента.

До Oracle 11.2 я использовал пользовательскую агрегатную функцию для объединения столбца в строку. 11.2 Добавлена LISTAGG функция, поэтому я пытаюсь использовать ее вместо этого. Моя проблема в том, что мне нужно устранить дубликаты в результатах и, похоже, я не могу этого сделать.

То, что я хочу увидеть, это:

Вот listagg версия, которая близка, но не устраняет дубликаты.

У меня есть решение, но это хуже, чем продолжать использовать пользовательскую функцию агрегирования.

Должно order by null быть order by Num2 или я запутался? @ Джек - Это не имеет значения для устранения дубликатов. В зависимости от вашего использования, это может быть желательно. вздох LISTAGG продолжает отставать от Тома Кайта STRAGG , с которым это так же легко, как STRAGG(DISTINCT . )

Вы можете использовать регулярные выражения и regexp_replace удалить дубликаты после объединения listagg :

Это может быть проще, если Oracle поддерживает регулярные выражения или группы без захвата, но это не так .

Однако это решение позволяет избежать сканирования источника более одного раза.

Обратите внимание, что для того, чтобы этот метод REGEX_REPLACE работал для удаления дубликатов, все дублированные значения должны быть рядом друг с другом в агрегированной строке. Вот чего ORDER BY Num2 добивается, не правда ли (см. Здесь ). Или вы просто пытаетесь указать, что вам нужен ORDER BY, чтобы он работал?

Насколько я вижу, с доступной на данный момент спецификацией языка это самый короткий путь для достижения того, чего вы хотите, если это необходимо сделать listagg .

Каким было ваше решение, которое было хуже, чем нестандартное совокупное решение ?

Это работает, но нужно сделать два полных сканирования таблицы. Если у вас небольшая таблица, которую нужно агрегировать (<100000 строк), производительность будет более чем приемлемой для простого извлечения. Это было мое решение выбора после почти часа тестирования всех возможных способов! Это также работает, когда дубликаты помещают промежуточное значение более 4000 символов. Это делает его более безопасным, чем regexp решение.

Я тестирую что-то в Oracle и заполнил таблицу некоторыми примерами данных, но в процессе я случайно загрузил дублирующиеся записи, поэтому теперь я не могу создать первичный ключ, используя некоторые столбцы.

Как я могу удалить все повторяющиеся строки и оставить только одну из них?

Используйте rowid псевдостолбец.

Где column1 , column2 и column3 составляют идентифицирующий ключ для каждой записи. Вы можете перечислить все свои столбцы.

+1 Мне нужно было найти два дубликата телефонных номеров в более чем 12 000 записей. Поменял DELETE на SELECT, и это нашло их за считанные секунды. Спасла меня куча времени, спасибо. Этот подход не работал для меня. Я не знаю почему. Когда я заменил «DELETE» на «SELECT *», он вернул строки, которые я хотел удалить, но когда я выполнял с «DELETE», он просто зависал бесконечно. Моя тоже либо висит, либо просто выполняется очень долго. Бегал около 22 часов и все еще еду. Таблица имеет 21M записей. Я предлагаю добавить дополнительную фильтрацию в оператор WHERE, если у вас очень большой набор данных и, если это возможно, это может помочь людям с длительными запросами. Если выбор работает, а удаление - нет, это может быть связано с размером результирующего подзапроса. Возможно, было бы интересно сначала создать таблицу с результатом подзапроса, построить индекс для столбца min (rowid), а затем выполнить оператор delete.

(исправлена ​​пропущенная скобка)

Скобки отсутствуют в утверждении. Я полагаю, это должно быть в конце?

Где column1, column2 и т. Д. - это ключ, который вы хотите использовать.

Повторяю мой комментарий выше об ответе с наибольшим количеством голосов, именно этот запрос фактически решил мою проблему. На огромных столах это будет намного медленнее, чем решение Билла.

создать таблицу t2 как выделенную * из t1;

не ответ - distinct * возьмет каждую запись, которая отличается как минимум 1 символом в 1 столбце. Все, что вам нужно, это выбрать отдельные значения только из столбцов, которые вы хотите сделать первичными ключами - ответ Билла является отличным примером такого подхода. Это было то, что мне было нужно (убрать полностью идентичные строки). Спасибо ! Еще один недостаток этого метода заключается в том, что вам необходимо создать копию таблицы. Для огромных таблиц это подразумевает предоставление дополнительного табличного пространства и удаление или сокращение табличного пространства после копирования. Метод Билла имеет больше преимуществ и никаких дополнительных недостатков.

Вы должны сделать небольшой блок pl / sql, используя курсор для цикла, и удалить строки, которые вы не хотите сохранять. Например:

Я полагаю, что отрицательный результат заключается в том, что вы используете PL / SQL, когда вы можете сделать это в SQL, если вам интересно. То, что вы можете сделать это в SQL, не означает, что это единственное решение. Я опубликовал это решение после того, как увидел решение только для SQL. Я думал, что голоса были за неправильные ответы.

Для выбора дубликатов можно использовать только формат запроса:

Таким образом, правильный запрос согласно другому предложению:

Этот запрос сохранит самую старую запись в базе данных по критериям, выбранным в WHERE CLAUSE .

Oracle Certified Associate (2008)

Самый быстрый способ для действительно больших столов

Создайте таблицу исключений со структурой ниже: exceptions_table

Присоединяйся к своей таблице с помощью exception__table по rowid и удалите дубли

Если количество удаляемых строк велико, создайте новую таблицу (со всеми разрешениями и индексами), которая не будет объединяться с помощью exceptions_table по rowid, и переименуйте исходную таблицу в таблицу original_dups и переименуйте new_table_with_no_dups в исходную таблицу.

Используя самостоятельное соединение

плотный ранг с разделением на дает ранг для дублирующихся строк с одинаковым номером, например три строки с рангом 1, 1, 1 и rowid создают для каждой строки как unic, и мы пытаемся удалить те строки, которые не совпадают. мы можем использовать функции и ранга, и плотного_ранка, но я думаю, что ранг отлично работает в этом сценарии.

1. решение

2. sloution

3.solution

4. решение

5. решение

и вы также можете удалить дубликаты записей другим способом

Тот же ответ, что и более сложный ответ Билла Ящерицы. Можете ли вы добавить больше информации о вашем пути? Спасибо.

Для лучшей производительности вот что я написал:
(см. План выполнения)

Проверьте ниже скрипты -

Вы увидите здесь 6 записей.
4. запустить под запросом -

Вы увидите, что дубликаты записей были удалены.
Надеюсь, что это решит ваш запрос. Спасибо :)

Что стоит отметить:

1) Мы проверяем дублирование только в полях раздела.

2) Если у вас есть причина выбрать один дубликат среди других, вы можете использовать предложение order by, чтобы в этой строке было row_number () = 1

3) Вы можете изменить сохраненный дубликат числа, изменив конечное условие where на «Where RN> N» с N> = 1 (я думал, что N = 0 удалит все строки, которые имеют дубликаты, но он просто удалит все строки) ,

4) Добавлено поле «Сумма раздела» в запросе CTE, в котором каждая строка будет помечена номерами строк в группе. Поэтому, чтобы выбрать строки с дубликатами, включая первый элемент, используйте «WHERE cnt> 1».

Читайте также: