在T-SQL中,如何检查字符串是否包含两个或多个相似的字符?
我的列包含nvarchar的手机号码,可能是“5512111445”,“6612888445”或隐藏号码,如“5512zzz44x”
我有一个用户输入的搜索模式,可能是“xx12yyy4zx”,我想将所有匹配的数字返回到这个模式,其中x,y,z表示任意数字,但如果重复它将表示相同的数。例如,上一个模式应该返回上面列出的所有数字。
xx是相似的数字,如55或66 ..而xy是不同的数字,如45或67 ..
如何做到这一点?
答案 0 :(得分:2)
我不打算对整个事情进行编码,因为它会很乏味,但我认为这可以让你开始。
... mobile_num like '551200044_' or mobile_num like '551211144_' ... or mobile_num_like '551299944_'
我们的想法是逐步过滤出结果,直到你只剩下与原始模式匹配的#。
可能有更有效的方法来做到这一点。如果部署CLR是一个选项,那么使用CLR&常用表达。
答案 1 :(得分:2)
您可以将蒙版中的每个字符和数字转换为列,然后仅在蒙版上分组,然后是蒙版+数字。在此方法中,5512111445和6612888445与掩码xx12yyy4yz不匹配,因为掩码中的y未映射到唯一数字。但是,手机号码5512111415和6612888485匹配掩码xx12yyy4yz,手机号码5512zzz44x也是如此。
--declare @mobileNums varchar(10)='5512111445'; --no match because @mask y maps to different values
--declare @mobileNums varchar(10)='6612888445'; --no match because @mask y maps to different values
--declare @mobileNums varchar(10)='5512111415'; --no match because @mask x should not equal @mask z
--declare @mobileNums varchar(10)='6612888485'; --matches
--declare @mobileNums varchar(10)='8812888485'; --no match because @mask x should not equal @mask y
--declare @mobileNums varchar(10)='5512zzz44x'; --matches because z and x are both hidden and different
--declare @mask varchar(10)='xx12yyy4yz';
declare @mobileNums varchar(10)='3211zyy'; -- no match because @mask y <> @mask z, but @mobileNums y = y
declare @mask varchar(10)='3211yxz';
declare @t table(n char, m char);
declare @i int=1;
while @i<=LEN(@mobileNums) begin
insert into @t values (SUBSTRING(@mobileNums,@i,1), SUBSTRING(@mask,@i,1));
set @i+=1;
end
if exists(
-----------------------------------------------------------------------------
-- Group by m
select
m, c=count(m)
from @t
where ISNUMERIC(n)=0 and ISNUMERIC(m)=0
group by m
except
select
m, c=count(m+n)
from @t
where ISNUMERIC(n)=0 and ISNUMERIC(m)=0
group by m,n
union
select
m, c=count(m)
from @t
where ISNUMERIC(n)=0 and ISNUMERIC(m)=1
group by m
except
select
m, c=count(m+n)
from @t
where ISNUMERIC(n)=0 and ISNUMERIC(m)=1
group by m,n
union
select
m, c=count(m)
from @t
where ISNUMERIC(n)=1 and ISNUMERIC(m)=0
group by m
except
select
m, c=count(m+n)
from @t
where ISNUMERIC(n)=1 and ISNUMERIC(m)=0
group by m,n
union
select
m, c=count(m)
from @t
where ISNUMERIC(n)=1 and ISNUMERIC(m)=1
group by m
except
select
m, c=count(m+n)
from @t
where ISNUMERIC(n)=1 and ISNUMERIC(m)=1
group by m,n
union
-----------------------------------------------------------------------------
-- Group by n
-- Add a rule that no numeric @mobileNums digit can correspond to more than one alpha @mask character
select
n, c=count(m)
from @t
where ISNUMERIC(n)=1 and ISNUMERIC(m)=0
group by n
except
select
n, c=count(m+n)
from @t
where ISNUMERIC(n)=1 and ISNUMERIC(m)=0
group by m,n
union
-- For GROUP BY n, include the three remaining combinations of ISNUMERIC(n) and ISNUMERIC(m)
select
n, c=count(m)
from @t
where ISNUMERIC(n)=0 and ISNUMERIC(m)=0
group by n
except
select
n, c=count(m+n)
from @t
where ISNUMERIC(n)=0 and ISNUMERIC(m)=0
group by m,n
union
select
n, c=count(m)
from @t
where ISNUMERIC(n)=0 and ISNUMERIC(m)=1
group by n
except
select
n, c=count(m+n)
from @t
where ISNUMERIC(n)=0 and ISNUMERIC(m)=1
group by m,n
)
select patMatch='False'
else
select patMatch='True';
编辑 - 添加一条规则,即没有数字@mobileNums数字可以对应多个alpha @mask字符
编辑 - 对于GROUP BY n
,请包含ISNUMERIC(n)和ISNUMERIC(m)的其余三个组合
编辑 - 删除第八个UNION