Что эквивалентно REGEXP_SUBSTR в MySQL? - PullRequest
9 голосов
/ 30 апреля 2010

Я хочу извлечь слово из строкового столбца таблицы.

description
===========================
abc order_id: 2 xxxx yyy aa
mmm order_id: 3 nn kk yw

Ожидаемый набор результатов

order_id
===========================
2
3

В таблице не более 100 строк, длина текста ~ 256 символов, а в столбце всегда присутствует один order_id. Так что производительность не проблема.

В Oracle я могу использовать REGEXP_SUBSTR для этой проблемы. Как бы я решить это в MySQL?

Редактировать 1

Я использую LOCATE и SUBSTR для решения проблемы. Код ужасен. Через десять минут после написания кода я проклинаю парня, который написал такой уродливый код.

Я не нашел функцию REGEXP_SUBSTR в документах MySQL. Но я надеюсь, что это существует ..

Ответ: Почему нельзя оптимизировать таблицу? Почему данные хранятся в такой тупой форме?

Пример, который я привел, обозначает проблему, которую я пытаюсь решить. В реальном сценарии я использую стороннее программное обеспечение для организации очередей для выполнения асинхронных задач. Очередь сериализует объект Ruby как текст. У меня нет контроля над структурой таблицы ИЛИ форматом данных. Задачи в очереди могут повторяться. В нашей тестовой настройке некоторые повторяющиеся задачи не выполняются из-за устаревших данных. Я должен удалить эти задачи, чтобы предотвратить ошибку. Такие ошибки не распространены, поэтому я не хочу поддерживать нормализованную теневую таблицу.

Ответы [ 4 ]

5 голосов
/ 30 апреля 2010

Как сказал Конерак, в MySql нет эквивалента REGEXP_SUBSTR. Вы можете делать то, что вам нужно, используя логику SUBSTRING, но это ужасно:

SELECT
  SUBSTRING(lastPart.end, 1, LOCATE(' ', lastPart.end) - 1) AS orderId
FROM
  (
    SELECT
      SUBSTRING(dataset.description, LOCATE('order_id: ', dataset.description) + LENGTH('order_id: ')) AS end
    FROM
      (
        SELECT 'abc order_id: 2 xxxx yyy aa' AS description
        UNION SELECT 'mmm order_id: 3 nn kk yw' AS description
        UNION SELECT 'mmm order_id: 1523 nn kk yw' AS description
      ) AS dataset
    ) AS lastPart

Редактировать: Вы можете попробовать эту пользовательскую функцию , обеспечивающую доступ к регулярному выражению perl в MySql

SELECT 
  PREG_CAPTURE( '/.*order_id:\s(\d+).*/', dataset.description,1)
FROM
  (
    SELECT 'abc order_id: 2 xxxx yyy aa' AS description
    UNION SELECT 'mmm order_id: 3 nn kk yw' AS description
    UNION SELECT 'mmm order_id: 1523 nn kk yw' AS description
  ) AS dataset
4 голосов
/ 19 апреля 2018

"Я не нашел функцию REGEXP_SUBSTR в документах MySQL. Но я надеюсь, что она существует .."

Да, начиная с MySQL 8.0, это поддерживается. Регулярные выражения :

REGEXP_SUBSTR(expr, pat[, pos[, occurrence[, match_type]]])

Возвращает подстроку строки expr, которая соответствует регулярному выражению, указанному в шаблоне pat, NULL, если совпадений нет. Если expr или pat NULL, возвращаемое значение NULL.

1 голос
/ 20 ноября 2016

или вы можете сделать это и уберечь себя от уродства:

select SUBSTRING_INDEX(SUBSTRING_INDEX('habc order_id: 2 xxxx yyy aa',' ',3),' ',-1);
1 голос
/ 30 апреля 2010

Нет аналога MySQL. MySQL REGEXP можно использовать для сопоставления строк, но не для их преобразования.

Вы можете попытаться работать с хранимыми процедурами и большим количеством логики REPLACE / SUBSTRING, или сделать это на своем языке программирования - что должно быть самым простым вариантом.

Но вы уверены, что ваш формат данных выбран правильно? Если вам нужен order_id, не имеет ли смысла хранить его в другом столбце, чтобы вы могли размещать индексы, использовать объединения и тому подобное?

...