繁体   English   中英

如何在mssql中搜索可以以不同格式存储的字符串(电话号码)

[英]How to search a string(Phone number) which can be stored in different format in mssql

我有一张客户表,其中电话号码字段定义为varchar(50)。 由于没有验证,因此不同的客户已经以自己喜欢的方式保存了电话号码,例如

cust1-> xxx-xxx-xxx

客户2->(xxx)xxx-xxx

cust3-> xxx xxx xxx

到目前为止,这还没有造成任何问题,因为没有人使用电话号码进行搜索。 添加搜索功能后,客户端无法获得所需的结果,因为要匹配您还必须以相同的格式提供查询。

有什么方法可以只考虑数字来搜索“电话”列?

我的答案与Andy Korneyev的答案非常相似,但我将添加一些额外的细节。

为什么一个具有标准化电话号码的列?

如果表中有很多行,建议您使用标准化格式的列,这样,当您的用户想要查找电话号码时,应用程序会对其进行标准化并进行查找。

如果您使用任何解决方案通过规范化用户条目以及表列中的值来进行查询,则服务器必须做额外的工作,并且没有机会使用索引。

因此,到目前为止,最好的解决方案是使用标准化列。

可以直接从应用程序中创建此列,也可以将触发器应用于原始表以创建规范化的列(我个人不会使用触发器)。

关于保留使用索引的前缀该怎么办?

最后,在查找电话号码时有一个典型情况:有时人们包括前缀,有时没有。 因此,您必须使用类似WHERE T.PhoneNumber LIKE '%5551234'这样的谓词。 如果这样做,将您的电话号码列编入索引将不会有任何好处。

为了解决这个典型的问题,将数字归一化并取反,即将先前的样本存储为:例如,如果有前缀,则为“ 4321555”或“ 4312555070”。

除了规范化(即删除非数字)外,当用户寻找“ 5551234”甚至是“ 0705551234”时,应用程序可以将其取反,并使用如下谓词:

WHERE T.PhoneNumber LIKE '4321555%' OR '4321555' LIKE T.PhoneNumber+'%'

第一部分介绍了数据库中的数字带有前缀而用户未指定前缀的情况。 (即,存储的电话号码是4321555070

第二部分介绍了相反的情况。 通过此示例,您会更清楚地看到它(当存储的电话号码为4321555 ):

WHERE T.PhoneNumber LIKE '4321555070%' OR '4321555070' LIKE T.PhoneNumber+'%'

这就是为什么在许多CRM中您会发现“ ReversedPhoneNumber”字段的原因。

顺便说一句,当您反转数字时,如果有可用的索引,它将被使用,从而加快了搜索速度。

简单的解决方案:

  1. 创建另一列将包含“纯净的”数字。
  2. 通过删除括号,空格,破折号等,从具有电话号码的现有电话号码中填充该号码-仅保留数字。
  3. after insert, update写入after insert, update表上的触发器,它将填充旧表中的新列。
  4. 在该新列上建立索引。

现在,您可以从搜索查询中删除所有“非数字”,只需使用新列进行搜索。

或者,如果您的数据库非常小-您可以“即时”删除查询中的所有“非数字”-但在这种情况下,即使您在phone列上建立了索引,也不会使用索引。

SELECT customer, phonenum
FROM table
WHERE replace(replace(replace(replace(phonenum,'-',''),'(',''),')',''),' ','') like '%1234%'

like '%1234%'替换为用于定义搜索的任何参数

使用以下功能从电话号码中提取INT值:

CREATE FUNCTION ExtractInteger(@String VARCHAR(2000))
RETURNS VARCHAR(1000)
AS
BEGIN
    DECLARE @Count INT
    DECLARE @IntNumbers VARCHAR(1000)
    SET @Count = 0
    SET @IntNumbers = ''

    WHILE @Count <= LEN(@String)
    BEGIN
    IF SUBSTRING(@String,@Count,1) >= '0'
    AND SUBSTRING(@String,@Count,1) <= '9'
    BEGIN
    SET @IntNumbers = @IntNumbers + SUBSTRING(@String,@Count,1)
    END
    SET @Count = @Count + 1
    END

RETURN @IntNumbers
END

搜索 电话号码如下:( '323-111'='(323)111')

DECLARE @SearchNumber VARCHAR(1000)
SET @SearchNumber = '323-111'
SELECT 'MatchFount' AS RESULT 
 WHERE dbo.ExtractInteger(@SearchNumber) 
    LIKE '%'+ dbo.ExtractInteger('(323)111')+'%'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM