SQL LIKE语句多条件贪婪加权匹配算法(改进版)

     上一篇博客:SQL LIKE语句多条件贪婪匹配算法


     直接入题,其他的就不罗嗦了。

     上篇博客仅仅是实现了多个关键字“尽可能多的匹配”。

     但是在实际应用中,尽可能多的匹配不一定合理。

     就拿“如何在CSDN网站注册用户”这句话来说,拆成“CSDN”、“注册”、“用户”这三个词。假如数据库中某条记录匹配了“CSDN”、“注册”这两个词,另一条记录匹配了“注册”、“用户”这两个词。两条记录中匹配词的个数都是两个,如果仅仅用上一篇博客的算法,这两个记录是对等的,而显然,他们不是对等的!“CSDN”这个词在这句话中至关重要,他是先决条件。因此,匹配“CSDN”、“注册”这两个词的记录要比匹配“注册”、“用户”这两个词的记录优先。

     基于以上事实,让我们清醒的意识到关键词并不是对等的,应该给他们分配一个权重,权重高的优先。

     SQL LIKE语句多条件贪婪匹配加权改进版:

GO
CREATE function Get_StrArrayLength
(
 @str varchar(1024),  --要分割的字符串
 @split varchar(10)  --分隔符号
)
returns int
as
 begin
  declare @location int
  declare @start int
  declare @length int
  set @str=ltrim(rtrim(@str))
  set @location=charindex(@split,@str)
  set @length=1
   while @location<>0
     begin
      set @start=@location+1
      set @location=charindex(@split,@str,@start)
      set @length=@length+1
     end
   return @length
 end
 GO
 CREATE function Get_StrArrayStrOfIndex
(
 @str varchar(1024),  --要分割的字符串
 @split varchar(10),  --分隔符号
 @index int --取第几个元素
)
returns varchar(1024)
as
begin
 declare @location int
 declare @start int
 declare @next int
 declare @seed int
 set @str=ltrim(rtrim(@str))
 set @start=1
 set @next=1
 set @seed=len(@split)
 set @location=charindex(@split,@str)
 while @location<>0 and @index>@next
   begin
    set @start=@location+@seed
    set @location=charindex(@split,@str,@start)
    set @next=@next+1
   end
 if @location =0 select @location =len(@str)+1
 
--这儿存在两种情况:1、字符串不存在分隔符号 2、字符串中存在分隔符号,跳出while循环后,@location为0,那默认为字符串后边有一个分隔符号。
 return substring(@str,@start,@location-@start)
end
GO
CREATE PROCEDURE proc_Common_SuperLike
	--要查询的表的主键字段名称
	@primaryKeyName varchar(999),
	--要查询的表名
	@talbeName varchar(999),
	--要查询的表的字段名称,即内容所在的字段
	@contentFieldName varchar(999),
	--查询记录的个数(TOP *),匹配的个数越多,排名越靠前
	@selectNumber varchar(999),
	--匹配字符分隔标记
	@splitString varchar(999),
	--匹配字符组合字符串
	@words varchar(999)
	
AS
	declare @sqlFirst varchar(999)
	declare @sqlCenter varchar(999)
	declare @sqlLast varchar(999)
BEGIN
	set @sqlCenter=''
	declare @next int  
	declare @arrayLength int
	set @next=1
	set @arrayLength=dbo.Get_StrArrayLength(@words,@splitString)
	while @next<=@arrayLength
	begin
		--构造sql查询条件(中间部分)
		set @sqlCenter = @sqlCenter+'SELECT '+@primaryKeyName+','+CONVERT(varchar(999),@arrayLength-@next+1)+' AS wordPower FROM '+@talbeName+' WHERE '+@contentFieldName+' like ''%'+dbo.Get_StrArrayStrOfIndex(@words,@splitString,@next)+'%'' UNION ALL '
		set @next=@next+1
	end
	--处理sql语句中间部分,去除最后无用语句
	set @sqlCenter=left(@sqlCenter,(len(@sqlCenter)-10))
	--构造sql语句开头部分
	set @sqlFirst='SELECT TOP '+@selectNumber+' '+@primaryKeyName+',COUNT(*)+SUM(wordPower) AS finalPower FROM ('
	--构造sql语句结尾部分
	set @sqlLast=') AS t_Temp GROUP BY '+@primaryKeyName+' ORDER BY finalPower DESC'
	--拼接出完整sql语句,并执行
	execute(@sqlFirst+@sqlCenter+@sqlLast)
END

     调用方法和第一个版本一样:

execute proc_Common_SuperLike 'id','t_test','content','20','|','i|o|c'

     id表的主键字段名称。

     t_test表名。

     content匹配内容字段名称。

     20选出20个记录(从顶至下匹配度越来越低)。

     |关键字的分隔符号。

     i|o|c一共有i,o,c三个关键字,通过|分隔。

 

     不同的是,关键字有了权重的概念。

     规则:i|o|c这三个关键字,权重依次降低,i的权重是3,o的权重2,c的权重是1。

     也就是说,把重要的关键字靠前放,不重要的关键字靠后放,越靠前权重越高。

 

     需要说明的是:

 

     本算法以权重+匹配数综合结果作为判断标准,而不再是一味的贪婪。

     比如有a|b|c|d|e五个关键字,按照规则,权重分别是:a-5、b-4、c-3、d-2、e-1,假如某条记录匹配了a、b、c三个关键字,另一条记录匹配了b、c、d、e四个关键字。

     依照算法:

     第一条记录最终权重是5(a权重)+4(b权重)+3(c权重)+3(匹配数)=15

     第二条记录最终权重是4(b权重)+3(c权重)+2(d权重)+1(e权重)+4(匹配数)=14

     因此优先选择第一条记录,虽然第一条记录的匹配数没有第二条多,但最终权重高。

 

     原创算法,欢迎转载,可用于任何用途,注明出处即可。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在SQL语句中,LIKE可以用来模糊匹配某个字段的值。对于多个条件的情况,可以使用通配符%和_来进行匹配。 比如下面的语句可以匹配字段name中以字母a开头的所有值: SELECT * FROM table WHERE name LIKE 'a%' 其中%表示任意字符,可以匹配任意个数的字符,也就是说,这个语句可以匹配“apple”、“amazing”、“ant”等等任何以a开头的单词。 如果要匹配多个条件,我们可以使用OR或者AND连接多个LIKE语句。比如下面的语句可以匹配字段name中以字母a或者e开头的所有值: SELECT * FROM table WHERE name LIKE 'a%' OR name LIKE 'e%' 这里使用了OR来连接两个LIKE语句,表示只要匹配到其中一个条件就可以返回结果。 另外,我们还可以使用通配符_来匹配单个字符。比如下面的语句可以匹配字段name中第二个字母是o的所有值: SELECT * FROM table WHERE name LIKE '_o%' 这里使用了_来匹配name中的第二个字符,表示只要第二个字符是o,后面可以匹配任意字符都可以返回匹配结果。 总之,当我们需要在SQL语句中使用LIKE进行模糊匹配时,可以使用通配符%和_来匹配任意个数或者单个字符,而在匹配多个条件时,可以使用OR和AND来连接多个LIKE语句。 ### 回答2: 在SQL语句中,like是用来模糊匹配字符串的操作符,它可以在查询数据时根据指定的模式匹配字符串,并返回符合条件的记录。对于需要搜索多个条件的情况,我们可以采用如下写法: 1.使用and进行多个条件匹配 使用and可以将多个模糊匹配条件连接起来,例如: select name,age from user where name like '%张%' and name like '%三%'; 在上述语句中,我们查询了名字中包含“张”和“三”的用户,其中%代表任意字符。 2.使用or进行多个条件匹配 和and类似,使用or可以连接多个模糊匹配条件,并返回符合任一条件的记录。例如: select name,age from user where name like '%张%' or name like '%三%'; 在上述语句中,我们查询了名字中包含“张”或“三”的用户。 3.使用in进行多个条件匹配 在有些情况下,我们只需要匹配指定的一些模式。此时,可以使用in操作符,指定多个匹配模式。例如: select name,age from user where name like '%张%' or name like '%李%' or name like '%王%'; 上述语句可以写成: select name,age from user where name like in('%张%','%李%','%王%'); 在上述语句中,我们查询了名字中包含“张”、“李”或“王”的用户。 综上所述,我们可以采用and、or和in等操作符来实现多个条件的模糊匹配,具体使用哪种方式取决于实际需求。在写SQL语句时,务必注意语法的正确性。 ### 回答3: 在进行数据库查询时,我们经常会使用 SQL 语句中的 LIKE 关键字进行模糊查询。而在需要同时匹配多个条件时,我们可以通过使用通配符和运算符来实现。以下是一些常用的 LIKE 多个条件的写法: 1. 通配符 _ 和 % LIKE 操作符支持两种通配符:_ 和 %,其中,_ 表示匹配任意单个字符,% 表示匹配任意多个字符。因此,可以使用这些通配符将多个条件组合在一起,如: SELECT * FROM table WHERE column1 LIKE 'a%' OR column1 LIKE '%b'; 上述语句匹配以 a 开头或以 b 结尾的 column1 字段值。 2. IN 运算符 IN 运算符可以用于检索字段值是否存在于一个集合中。因此,我们可以使用 IN 运算符将多个条件组合起来,如: SELECT * FROM table WHERE column1 IN ('a', 'b', 'c'); 上述语句匹配 column1 字段值为 a、b 或 c 的记录。 3. NOT LIKE 操作符 此外,如果我们需要排除某些条件,则可以使用 NOT LIKE 操作符来实现。如: SELECT * FROM table WHERE column1 NOT LIKE '%a%'; 上述语句匹配 column1 字段值中不包含 a 的记录。 综上所述,我们可以根据实际需求灵活运用通配符、运算符和 NOT LIKE 操作符,以实现 LIKE 多个条件的查询。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值