在mysql中搜索电话号码

时间:2020-03-05 18:46:48  来源:igfitidea点击:

我有一张桌子,上面满是任意格式的电话号码

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个"解决方案"

  • 一起整理CONCATSUBSTR的弗兰肯查询
  • 在针的每个字符之间插入一个"%"(所以就像这样:"%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个客户的表中,从用户界面发出此查询后,立即返回,没有明显的延迟。