MySQL 5.7 Сравните только цифры из смешанного столбца VARCHAR - PullRequest
3 голосов
/ 11 июня 2019

ПРИМЕЧАНИЕ: Обратите внимание, что это НЕ так же, как аналогично озаглавленных вопросов (см. «Что я уже пробовал» ниже)

Справочная информация:

Мне нужно найти в столбце строки базы данных номер телефона, который соответствует заданным критериям поиска.

Столбец базы данных представляет собой varchar с различными дополнительными (т.е. нечисловыми) символами, предоставленными пользователем.

Моя первоначальная идея состояла в том, чтобы использовать систему для преобразования строки столбца в числовой формат (в PHP это было бы через функции PCRE), а затем провести прямое идентичное сравнение

Пример хранимых данных:

id        telephone:
----------------------
 1     '01576 456 567'
 2     '07768345998'
 3     '+447588 43 34 56'
 4     '01524-901-335'

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

Проблема:

Не могу найти способ поиска в этом столбце числа. Я сократил поле поиска в PHP только до числа (0-9). Я хочу попробовать что-то вроде:

"Поиск в телефонном столбце и обнаружение, где числовое значение ТОЛЬКО (из смешанной строки) точно соответствует заданной строке поиска.

(псевдо-код:)

   SELECT telephone, id FROM phones WHERE 
          REGEX_REPLACE(`telephone`, '[^0-9]') = :searchNumber 

(: searchNumber является заполнителем PDO.)

Пример условия поиска:

"01576456567"

Ожидаемый результат:

После ввода поискового запроса в SQL-запрос я хочу получить номер идентификатора. В приведенном выше примере поиска; $result['id'] = 1;

Ограничения:

Это только для MySQL версии 5.7. Я не могу использовать MySQL 8.0 здесь.

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

Что я пробовал:

  • Функции типа REGEXP в MYSQL возвращают true / false (0/1) вместо обработанной REGEXP выходной строки.

  • CASE до SIGNED / UNSIGNED не работает, потому что разрывается в любом пробеле в строке и также может обрезать начальный ноль.

  • Я прочитал различные MySQL Ответы переполнения стека

Escape Clause:

Если мой запрос сбивает с толку, этот код PHP может быть лучшим примером того, чего я пытаюсь достичь

  • Если ничего не помогает, я могу экспортировать все числа и запустить их через цикл PHP, который будет делать то же самое:

    $searchNumber = preg_replace('/[^0-9]/','',$searchNumberSource);
    foreach ($numberFromDb as $row){
         if(preg_replace('/[^0-9]/',''.$row) === $searchNumberSource){
             // Matching number is found.
             break;
         }
    }
    

Ответы [ 2 ]

2 голосов
/ 11 июня 2019

Тривиальным способом является вложенное использование замены

select replace(replace(replace(telephone,' ',''), '-',''), '+','') 
1 голос
/ 11 июня 2019

Вы должны исправить данные так, чтобы они соответствовали тому, как вы хотите их использовать.Это может потребовать некоторых усилий сейчас, но исправление данных в дальнейшем упростит ваш код - вместо того, чтобы иметь трудные обходные пути.

Я предлагаю внести изменения на стороне приложения.Измените число на регулярное выражение:

SELECT telephone, id
FROM phones
WHERE telephone REGEXP :searchNumber_regex;

Тогда :searchNumber_regex для '"01576456567' будет выглядеть так:

'^[^0-9]*0[^0-9]*1[^0-9]*5[^0-9]*7[^0-9]*6[^0-9]*4[^0-9]*5[^0-9]*6[^0-9]*5[^0-9]*6[^0-9]*7[^0-9]*$'

По сути, шаблон [^0-9]* находится в начале иконец и между каждым номером.

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