[英]Phone number lookups using incoming numbers of varying lengths, with or without prefixes
系统:
-呼叫中心电话系统:传入呼叫以及源号码,主叫方ID(又称“ ANI”)
-SQL Server 2005-“数据仓库”,用于在表[CustDataByANI]中存储客户电话号码([cANI]),客户名称,位置等
-存储过程-呼叫中心软件将呼叫者ID(又称ANI)作为参数传递给SP,该参数使用它在CustDataByANI表上执行当前简单的SELECT语句。...WHERE [cANI] = @ANI。
如果查询找到@ANI与“查找表”中包含的686K cANI值之一之间的精确匹配,则此方法效果很好。 这种情况仅发生大约12%的时间。
目标:增加成功的“可能/可能”比赛的次数
重要说明:我们使用的是全局数据集,因此无法执行有关任一值(参数@ANI或[cANI]中的值)长度的规则。
情况1:
电话系统发送源号码“ 9876543210”,用作参数@ANI
该确切数字存在于CustDataByANI表的[cANI]列中(记录号55555)
Select语句从与记录55555 Super-easy关联的许多其他列中返回值:WHERE [cANI] = @ANI成功。
情况2:
@ANI =' 1 9876543210'(与上述相同,但前导'1')
在CustDataByANI.cANI中找不到完全匹配的项
[cANI]中最接近的匹配是'9876543210'(仍然记录55555)
甚至一个孩子都会意识到,与案例1的唯一区别是参数@ANI中存在一个1位数的“前缀”-也许是长途“标签”或国家/地区代码。
这样的前缀长度可能是1或2或什至3位数。...我们无法预测。 我们不想考虑大于3的前缀,但是在这种情况下,确实希望像情况1一样从记录55555返回值。
案例3:案例2的“反向”
@ANI ='9876543210'
在CustDataByANI.cANI中找不到完全匹配的项
[cANI]中最接近的匹配是' 1 9876543210'(记录#55555现在具有'1'前缀)
再一次,我们将假定两者是实质等同的。 在这种情况下,由于前缀,[cANI]值包含更长的序列,长度可能是1或2甚至是3位数...我们无法预测。 我们不想考虑大于3的前缀,但是在这种情况下,确实希望像情况1一样从记录55555返回值。
同样,由于每个值(@ANI和[cANI])的长度可能存在变化,并且由于我几乎完全缺乏SQL编程,因此我无法为存储过程编写一个考虑了所有3种情况的SELECT语句。 简单的带有通配符的“ LIKE”语句似乎失败了,我的头脑在旋转CASE准则,CONTAINS甚至REVERSE策略,以从右到左的方式“读取” @ANI和cANI值。
我的梦想是返回两者之间最好的匹配 。
我的愚蠢程序如下; 任何帮助都将不胜感激!
顺便说一句,我的源表CustDataByANI确实包含一个RevANI列,它只是反向的cANI值。 最初,我以为解决方案可能是同时反转@ANI参数值并在[RevANI]列中找到最大匹配项,从而在每个变量的右侧保留任何通配符。 但是我仍然陷于困境,并且不确定这是否是最佳策略。
USE [GCC]
GO
/****** Object: StoredProcedure [dbo].[SP_GetCustDataByANI] Script Date: 10/07/2014 07:47:34 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_GetCustDataByANI]
@ANI varchar(80)
AS
BEGIN
SET NOCOUNT ON;
--Remove leading zeros from the varchar @ANI. I chose this method rather than risking
--the undesirable introduction of exponential notation when long characters are converted to
--integers and back...
IF ((LEN(@ANI) > 1) AND (LEFT(@ANI,1)= '0'))
BEGIN
SET @ANI = REPLACE(LTRIM(REPLACE(@ANI,'0',' ')),' ','0')
END
SELECT Id
,cANI
,cServiceClass
,cCompanyClass
,cContactName
,cContactDivision
,cContactDepartment
,cCompanyName
,cOrganizationName
,cContactCity
,cContactStateTerr
,cContactCountry
,cCompanyIsDistributor
,PrefAgentID
,PrefAgentID_SQUAL
,PrefRegionID_SQUAL
,VIP_CC
,VIP_TS
,TS_ACAT
FROM [dbo].[CustDataByANI]
WHERE ([cANI] = @ANI)
如果要加快查询速度,可以创建一个带有电话号码相反顺序的附加列,在此列上创建索引,然后使用LIKE谓词查询该号码,同时以相反的顺序传递搜索到的电话号码。 这将使查询尽可能快。 例如,对于示例数据,可以将其存储在新的ReversedPhoneNumber
列中:
6543211234 store as: 4321123456
16543211234 store as: 43211234561
0016543211234 store as: 4321123456100
当您需要通过6543211234
查询时,只需对其进行反向查询, 6543211234
在反向列中查找如下所示
WHERE ReversedPhoneNumber LIKE `6543211234%`
这将与存储的任何格式的数字都匹配,并且匹配速度非常快,因为这是一种简单而快速的索引查找。 (类似于“开始于”操作的LIKE
会寻找索引来寻找巧合)。
至于您需要应用的其他规则,您比我们更了解数据。 只需考虑所有可能的情况并进行一些测试,您就会获得需要应用的规则(不要加快速度,但要确保正确的匹配)。
您可以在ETL过程中冲销电话号码。
缺少详细信息可以提供更好的建议。
注意:如果无法将列和索引添加到现有表中,则只需创建一个差异表来保存与现有表相关的反向编号。 您还可以添加触发器来维护此表
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.