[英]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”字段的原因。
顺便说一句,当您反转数字时,如果有可用的索引,它将被使用,从而加快了搜索速度。
简单的解决方案:
after insert, update
写入after insert, update
表上的触发器,它将填充旧表中的新列。 现在,您可以从搜索查询中删除所有“非数字”,只需使用新列进行搜索。
或者,如果您的数据库非常小-您可以“即时”删除查询中的所有“非数字”-但在这种情况下,即使您在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.