表名:SP_Prefix
字段:SP_Name(服务商名) PrefixFrom(电话号码前缀起) PrefixTo(电话号码前缀止)
数据: AIS 081371 081376
DSTC 081700 081702
AIS 081720 081721
AIS 0817315 0817319
DSTC 0898903 0898909
... ... ...
说明:表中记录了各个电信服务商对应的电话号码起止段。要求对于任意电话号码,能从表中查出它属于哪个服务商。比如,给出电话号码0813718765309,能迅速查出它是属于AIS服务商的号码。
难点:电话号码前缀式长度不一致,有时6位(大多数),有时7位,而且每个服务商对应的记录有几百条,号码分配比较乱。
如果你的PrefixFrom和PrefixTo是整型类型的话使用大于和小于,再加上索引速度应该完全能满足条件吧?
前缀的长度是不同的,但是电话号码的长度应该是相同的吧?
那么你可以把前缀字段改为起始号码和结束号码:
AIS 0813710000000 0813769999999
这个修改规则很简单,起始前缀都补0,截止前缀都补9,很容易通过程序一次性修改。
然后拿电话号码0813718765309去比较一下大小就可以了:
select * from SP_Prefix where PrefixFrom<=0813718765309 and 0813718765309<=PrefixTo
select * from SP_Prefix where PrefixFrom<=substring('0813718765309',1,len(Photos)) and PrefixTo>=substring('0813718765309',1,len(Photos))
PrefixFrom、PrefixTo 改造两步走:首先位数统一,其次化为整型。
即统一为 7 位,不足末位补 0。因首位全为 0 ,故实际为 6 位整数。
如果要保留原始字段用于显示,可另做两个别名整型字段用作查询索引用。
采用以上园友统指的简单查询语句就可以了。
select * from SP_Prefix where PrefixFrom1<=813718 and 813718<=PrefixTo1
电话号码位数不一样也没关系,因为你比较的是字符串(字符串是从左1位1位比)。所以不必转型或者补位...... 直接比就行了。
declare @phone varchar(50)
select @phone='0813718765309' --位数可以随意长,50位够了吧
select SP_Name from SP_Prefix where @phone between PrefixFrom and PrefixTo -- 在数据没有重叠、完全合理的时候(如果一条是:from '081700' to '085000' 另一条:from '081755' to '081777'。那么@phone='0817554523234' 就会查出两条,这种就是数据不合理的时候,要注意!!所以我习惯加个 top 1 ,程序肯定不会出异常了,但问题也不会暴露了) 就能查出一个SP_Name所求。
置于高效的话就不是语句的问题,而是数据库优化的问题了,如果你的电信服务商表就几百几千行,也没有加索引的必要,速度足够了。