使用不同长度的传入号码查找电话号码,包括前缀或不包括前缀



系统:
-呼叫中心电话系统:来电附有来源号码,又名来电显示,又名"ANI"
-SQL Server 2005-将客户电话号码([cANI])、客户名称、位置等存储在表[CustDataByANI]中的"数据仓库"
-存储过程-呼叫中心软件将呼叫者ID(又名ANI)作为参数传递给SP,SP使用它在CustDataByANI表上执行当前简单的SELECT语句。。。。其中[cANI]=@ANI
如果查询在@ANI和"查找表"中包含的686K cANI值之一之间找到完全匹配的值,则此操作非常有效。这种情况只发生在大约12%的时间

目标:增加成功的"可能/可能"匹配次数

重要提示:我们使用的是全局数据集,不能强制执行任何一个值(参数@ANI或[cANI]中的值)的长度规则。
案例1:
电话系统发送源号码"9876543210",该号码用作参数@ANI
该确切数字存在于CustDataByANI表的[cANI]列中(记录#55555)
Select语句返回与记录55555关联的许多其他列中的值超级简单:WHERE[cANI]=@ANI成功

案例2:
@ANI="19876543210"(与上文相同,但带前导"1")
在CustDataByANI.cANI中找不到完全匹配
[cANI]中最接近的匹配项是"9876543210"(仍为55555)
即使是孩子也会意识到,与情况1的唯一区别是参数@ANI中存在一个1位数的"前缀"——可能是长途"标签"或国家代码
这样的前缀的长度可以是1、2甚至3位。。。。我们无法预测。我们不想考虑前缀长度超过3,但在这种情况下,我们确实希望返回记录55555中的值,如情况1所示。

案例3:案例2的"反面"
@ANI='9876543210'
在CustDataByANI.cANI中找不到完全匹配
[cANI]中最接近的匹配项是"19876543210"(记录#55555现在有一个"1"前缀)
再次,我们假设两者实质上是对等的。在这种情况下,[cANI]值由于前缀而包含较长的序列,其长度可以是1、2甚至3位。。。我们无法预测。我们不想考虑前缀长度超过3,但在这种情况下,我们确实希望返回记录55555中的值,如情况1所示。

同样,由于每个值(@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进行查询时,只需将其反转并在反转的列中查看,如所示

WHERE ReversedPhoneNumber LIKE `6543211234%`

这将以存储的任何格式匹配数字,而且速度非常快,因为这是一个简单快速的索引查找。(类似于"以开始"操作的LIKE将查找索引以查找巧合)。

至于你需要应用的其他规则,你比我们更了解数据。只需考虑所有可能的情况并进行一些测试,你就会得到你需要应用(不是为了加快速度,而是为了确保正确匹配)的规则。

您可以在ETL过程中反转电话号码。

缺少一些细节可以提供更好的建议。

注意:如果不能向现有表添加列和索引,只需创建一个差异表来保存与现有表相关的反向数字。您还可以添加触发器来维护此表

最新更新