[英]MySQL 5.7 Compare only numbers from a mixed VARCHAR column
NOTE: Please note this is NOT the same as similarly titled questions (see "What I've Tried", below)
注:请注意,这是不一样的类似名称的问题(请参阅“我试过”,下同)
I need to search a database string column for a phone number that matches a given search criteria. 我需要在数据库字符串列中搜索与给定搜索条件匹配的电话号码。
The database column is a varchar with various user supplied additional (ie non-numeric) characters. 数据库列是一个varchar,其中包含各种用户提供的附加(即非数字)字符。
My original idea was to use a system to convert the column string to a numeric only format (in PHP this would be via PCRE functions) and then do a straight indentical comparison 我最初的想法是使用一个系统将列字符串转换为仅数字格式(在PHP中这将通过PCRE函数),然后进行直接的缩进比较
id telephone: ---------------------- 1 '01576 456 567' 2 '07768345998' 3 '+447588 43 34 56' 4 '01524-901-335'
There are a variety of human readable formats held, these are submitted by the end user and are often historic. 存在各种人类可读格式,这些格式由最终用户提交并且通常是历史性的。
I can not find a way to search this column for a number. 我找不到在此列中搜索数字的方法。 I have stripped down the search field in PHP to number only (0-9).
我已经将PHP中的搜索字段剥离为仅数字(0-9)。 I want to try something like:
我想尝试类似的东西:
"Search the telephone column and find where the numeric ONLY value (from a mixed string) matches the given search string exactly.
“搜索电话栏,找到数字ONLY值(来自混合字符串)与给定搜索字符串完全匹配的位置。
(pseudo-code:)
(伪代码:)
SELECT telephone, id FROM phones WHERE REGEX_REPLACE(`telephone`, '[^0-9]') = :searchNumber
(:searchNumber is the PDO placeholder.) (:searchNumber是PDO占位符。)
"01576456567"
“01576456567”
From entering the search term into the SQL query I want to be able to retrieve the id number. 从输入搜索词到SQL查询,我希望能够检索id号。 In the above search example;
在上面的搜索示例中;
$result['id'] = 1;
This is on MySQL vesion 5.7 only. 这仅适用于MySQL vesion 5.7。 I can not use MySQL 8.0 here.
我不能在这里使用MySQL 8.0。
It would cause a lot of secondary work to convert the phone columns to numeric column types and we don't have the time flexibility to do this right now. 这会导致很多次要工作将电话列转换为数字列类型,我们现在没有时间灵活地执行此操作。
The REGEXP type functions on MYSQL return true
/ false
(0/1) rather than a REGEXP processed output string. MYSQL上的REGEXP类型函数返回
true
/ false
(0/1)而不是REGEXP处理的输出字符串。
CASE
to SIGNED
/ UNSIGNED
does not work because it breaks at any whitespace in the string and also can lop off the leading zero. CASE
到SIGNED
/ UNSIGNED
不起作用,因为它在字符串中的任何空格处断开,也可以丢掉前导零。
I have read various MySQL Stack Overflow answers 我已经阅读了各种 MySQL Stack Overflow答案
If my query is confusing this PHP code may better example what I'm trying to achieve. 如果我的查询混淆了这个PHP代码可能更好地举例说明我正在努力实现的目标。
If all else fails I can export all of the numbers and run them through a PHP loop which would do the same thing: 如果所有其他方法都失败了,我可以导出所有数字并通过PHP循环运行它们,这将做同样的事情:
$searchNumber = preg_replace('/[^0-9]/','',$searchNumberSource); foreach ($numberFromDb as $row){ if(preg_replace('/[^0-9]/',''.$row) === $searchNumberSource){ // Matching number is found. break; } }
一个简单的方法是嵌套使用replace
select replace(replace(replace(telephone,' ',''), '-',''), '+','')
You should fix the data so it matches how you want to use it. 您应该修复数据,使其符合您的使用方式。 That may take some effort now, but fixing the data will simplify your code ongoing -- rather than having arduous work-arounds.
这可能需要一些努力,但修复数据将简化您的代码 - 而不是艰苦的解决方案。
My suggestion is to make the change on the application side. 我的建议是在应用程序方面进行更改。 Change the number to a regular expression:
将数字更改为正则表达式:
SELECT telephone, id
FROM phones
WHERE telephone REGEXP :searchNumber_regex;
Then :searchNumber_regex
for '"01576456567'
would look like: 然后
: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]*$'
Basically, the pattern [^0-9]*
is at the beginning and end and in-between every number. 基本上,模式
[^0-9]*
位于开头和结尾,并且位于每个数字之间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.