在mysql中搜索电话号码
我有一张桌子,上面满是任意格式的电话号码
027 123 5644 021 393-5593 (07) 123 456 042123456
我需要以类似的任意格式搜索电话号码(例如," 07123456"应该找到条目"(07)123 456"
我将使用普通编程语言执行此操作的方法是将所有非数字字符从"针"中去除,然后遍历大海捞针中的每个数字,将所有非数字字符从中去除,然后与之进行比较针,例如(红宝石)
digits_only = lambda{ |n| n.gsub /[^\d]/, '' } needle = digits_only[input_phone_number] haystack.map(&digits_only).include?(needle)
问题是,我需要在MySQL中执行此操作。它具有许多字符串函数,这些函数似乎都无法真正实现我想要的功能。
目前我可以想到2个"解决方案"
- 一起整理
CONCAT
和SUBSTR
的弗兰肯查询 - 在针的每个字符之间插入一个"%"(所以就像这样:"%0%7%1%2%3%4%5%6%")
但是,这些似乎都不是特别优雅的解决方案。
希望有人可以提供帮助,否则我可能会被迫使用%%%%%%解决方案
更新:这是对一组相对固定的数据进行操作,可能有几百行。我只是不想做一些可笑的坏事,以至于将来的程序员会大哭一场。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。......。
如果数据集增加,我将采用" phoneStripped"方法。感谢所有反馈!
could you use a "replace" function to strip out any instances of "(", "-" and " ",
我不担心结果是数字。
我需要考虑的主要字符是+
,-
,(
,)
和space
。
那么该解决方案看起来像这样吗?
SELECT * FROM people WHERE REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(phonenumber, '('),')'),'-'),' '),'+') LIKE '123456'
那不是很慢吗?
解决方案
回答
一个开箱即用的想法,但是我们可以使用"替换"功能删除"(","-"和""的任何实例,然后使用" isnumeric"功能测试结果字符串是否是数字吗?
然后,我们可以对要搜索的电话号码字符串执行相同的操作,并将它们比较为整数。
当然,这不适用于1800-MATT-ROCKS之类的数字。 :)
回答
这是MySQL的问题,正则表达式函数可以匹配,但不能替换。请参阅此帖子以获取可能的解决方案。
回答
是否可以运行查询以重新格式化数据以匹配所需格式,然后仅运行简单查询?这样,即使初始重新格式化很慢,我们也没关系。
回答
MySQL can search based on regular expressions.
可以,但是给定了任意格式,如果我的干草堆中包含"((027)123 456""(记住空格的位置可以更改,则它可能很容易变成" 027 12 3456",我想将其与匹配) 027123456
,因此我的正则表达式需要是吗?
"^[\D]+0[\D]+2[\D]+7[\D]+1[\D]+2[\D]+3[\D]+4[\D]+5[\D]+6$"
(实际上,情况会更糟,因为mysql手册似乎并不表明它支持\ D
)
如果是这样,这与我的%%%%%想法差不多吗?
回答
只是一个想法,但是我们不能使用Regex快速删除字符,然后与@Matt Hamilton建议的字符进行比较吗?
甚至可以设置一个视图(不确定视图中是否使用mysql),该视图会将正则表达式剥离的所有电话号码保存为普通电话号码?
回答
麻烦是我。我最终这样做:
mre = mobile_number && ('%' + mobile_number.gsub(/\D/, '').scan(/./m).join('%')) find(:first, :conditions => ['trim(mobile_phone) like ?', mre])
回答
如果这是经常发生的事情,那么也许可以将数据修改为全部一种格式,然后设置搜索表单以去除任何非字母数字(如果允许使用310-BELL这样的数字)将是一个好主意。以易于搜索的格式存储数据是成功的一半。
回答
从一开始就看起来像是一个问题。我们进行的任何类型的搜索都需要进行表扫描,我们都知道这很不好。
除去所有格式字符后,如何添加带有当前电话号码的哈希值的列。然后,我们至少可以为哈希值建立索引,并避免进行完整的表扫描。
还是数据量很小并且预计增长不会很大?
然后,也许只是将所有数字都输入到客户端中并在其中进行搜索。
回答
我的解决方案将与约翰·代尔所说的类似。我要添加第二列(例如phoneStripped),该列会在插入和更新时被剥离。为该列建立索引并对其进行搜索(当然,在删除搜索词之后)。
我们也可以添加触发器以自动更新列,尽管我没有使用触发器。但是就像我们说的那样,编写MySQL代码来剥离字符串确实很困难,因此仅在客户端代码中执行操作可能会更容易。
(我知道这很晚了,但我才开始在这里四处看看:)
回答
一个可能的解决方案可以在以下网址找到://udf-regexp.php-baustelle.de/trac/
需要安装其他软件包,然后可以使用REGEXP_REPLACE
回答
看
http://www.mfs-erp.org/community/blog/find-phone-number-in-database-format-independent
正则表达式在视觉上会令人震惊,这并不是真正的问题,因为只有mysql才能看到它。请注意,我们应在正则表达式中使用" *",而不是" +"(在OP中以[\ D]开头)。
一些用户担心性能(非索引搜索),但是在有100000个客户的表中,从用户界面发出此查询后,立即返回,没有明显的延迟。