C# 在MS SQL Server 2008中,加入“最佳”匹配的好方法是什么?
本质上,我希望根据Call表中的TelephoneNumber字段从Rate表中选择前缀的最佳匹配。根据下面的示例数据,“0123456789”与前缀“012”最匹配,而“0100000000”与前缀“01”最匹配 我在SQL注释中包含了一些DML和一些正确匹配的示例 速率表中大约有70000行,调用表中大约有2000万行。但是,基于dateTime列,从调用表中选择将受到限制,因此实际上查询只需要运行50万个调用行 速率表中的前缀最长可达16个字符 我不知道如何在SQL中实现这一点,我目前正在考虑编写一个C SQLCLR函数来实现这一点。有人做过类似的事情吗?如果你有什么建议,我将不胜感激 示例数据 呼叫表:C# 在MS SQL Server 2008中,加入“最佳”匹配的好方法是什么?,c#,tsql,join,sqlclr,C#,Tsql,Join,Sqlclr,本质上,我希望根据Call表中的TelephoneNumber字段从Rate表中选择前缀的最佳匹配。根据下面的示例数据,“0123456789”与前缀“012”最匹配,而“0100000000”与前缀“01”最匹配 我在SQL注释中包含了一些DML和一些正确匹配的示例 速率表中大约有70000行,调用表中大约有2000万行。但是,基于dateTime列,从调用表中选择将受到限制,因此实际上查询只需要运行50万个调用行 速率表中的前缀最长可达16个字符 我不知道如何在SQL中实现这一点,我目前正在
Id TelephoneNumber
1 0123456789
2 0100000000
3 0200000000
4 0780000000
5 0784000000
6 0987654321
费率表:
Prefix Scale
1
01 1.1
012 1.2
02 2
078 3
0784 3.1
DML
注:最后一个“0987654321”与空白字符串匹配,因为没有更好的匹配。 尝试这一个:
select Prefix, min(c.TelephoneNumber)
from Rate r
left outer join Call c on c.TelephoneNumber like left(Prefix + '0000000000', 10)
or c.TelephoneNumber like Prefix + '%'
group by Prefix
因为这是基于部分匹配的,所以子选择将是唯一可行的选择,除非像LukeH假设的那样,每个调用都是唯一的
select
c.Id,
c.TelephoneNumber,
(select top 1
Scale
from Rate r
where c.TelephoneNumber like r.Prefix + '%' order by Scale desc
) as Scale
from Call c
您可以使用左连接来尝试找到更好的匹配,然后在where子句中消除此类匹配。e、 g:
select
*
from
Call c
inner join
Rate r
on
r.Prefix = SUBSTRING(c.TelephoneNumber,1,LEN(r.Prefix))
left join
Rate r_anti
on
r_anti.Prefix = SUBSTRING(c.TelephoneNumber,1,LEN(r_anti.Prefix)) and
LEN(r_anti.Prefix) > LEN(r.Prefix)
where
r_anti.Prefix is null
绩效有多重要?如果您需要高容量的分秒响应,可能需要设置额外的索引前缀表以避免模式匹配。谢谢-我将做一些性能测试,看看它是如何运行的-虽然报告将每月运行一次,因此性能不会太重要。谢谢,但仍然不太重要,我不知道你可以在连接中使用like操作符-这很酷。我正在根据你的答案尝试不同的变化。接受为答案谢谢。我已经稍微改变了它,根据前缀匹配的长度而不是比例来选择最好的-尽管我确信财务人员希望我总是选择最昂贵的!所以insead的顺序是按比例描述的。前缀是描述。@Adam:我的第一次尝试是因为误读了这个问题。现在修好了。
select
c.Id,
c.TelephoneNumber,
(select top 1
Scale
from Rate r
where c.TelephoneNumber like r.Prefix + '%' order by Scale desc
) as Scale
from Call c
select
*
from
Call c
inner join
Rate r
on
r.Prefix = SUBSTRING(c.TelephoneNumber,1,LEN(r.Prefix))
left join
Rate r_anti
on
r_anti.Prefix = SUBSTRING(c.TelephoneNumber,1,LEN(r_anti.Prefix)) and
LEN(r_anti.Prefix) > LEN(r.Prefix)
where
r_anti.Prefix is null