SQL LIKE语句多条件贪婪加权匹配(新增必要词指定)

前两篇博客:

 

        SQL LIKE语句多条件贪婪匹配算法

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

 

         为了更好的扩充本算法的适用范围,特加入必要关键词指定功能

         在实际应用中,很可能希望匹配的时候必须出现某个词,否则就是没有意义的匹配。

         说到这,读者可能觉得这些需求小题大做,在程序中用正则表达式很容易实现,再次重申,现在的矛盾是我们不能把记录返回到程序中处理,因为涉及到大数据量,必须考虑服务器承受能力、并发访问数量、网络传输能力、程序处理能力等诸多因素。在服务器端尽量缩小数据范围,减少数据传输量,无疑是最佳选择。

         这个版本加入的新特性即必要关键词指定,同样拿“如何在CSDN网站注册用户”这句话来说,“CSDN”这个词可以认为是必要词,因为它是前提,试想你在搜索“如何在CSDN网站注册用户”时,却出现了“如何在网易注册用户”,显然是毫无意义的结果。

         事实亦如此,地球人也是这么做的,在百度搜“如何在CSDN网站注册用户”,把结果从第一页翻到最后一页,可以发现每一个结果中都可以找到“CSDN”字眼。

         其实,大多数情况下,通过贪婪加权匹配,已经可以实现非常重要的词“必然”出现,但有时候需要做一个保证,让结果更加合理。

 

SQLLIKE语句多条件贪婪加权匹配(新增必要词功能):


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)
	declare @next int  
	declare @arrayLength int
	declare @newWords varchar(999)
	declare @newTable varchar(999)
BEGIN
	set @newTable=@talbeName
	set @newWords=@words
	set @next=dbo.Get_StrArrayLength(@words,'[')
	--判断是否有必要词
	if @next>1
	begin
		set @newTable=''
		--构造必要表sql语句
		while @next>1
		begin
			set @newTable=@newTable+@contentFieldName+' like ''%'+dbo.Get_StrArrayStrOfIndex(dbo.Get_StrArrayStrOfIndex(@words,'[',@next),']',1)+'%'' AND '
			set @next=@next-1
		end
		set @newTable=left(@newTable,(len(@newTable)-4))
		--构造临时表
		set @newTable='SELECT * into ##tempTable FROM '+ @talbeName + ' WHERE ' + @newTable
		execute(@newTable)
		--指定临时表
		set @newTable='##tempTable'
		--去掉关键词组中的必要词标记
		set @newWords=REPLACE(REPLACE(@words,'[',''),']','')
	end
	set @sqlCenter=''
	set @next=1
	set @arrayLength=dbo.Get_StrArrayLength(@newWords,@splitString)

	while @next<=@arrayLength
	begin
		--构造sql查询条件(中间部分)
		set @sqlCenter = @sqlCenter+'SELECT '+@primaryKeyName+','+CONVERT(varchar(999),@arrayLength-@next+1)+' AS wordPower FROM '+@newTable+' WHERE '+@contentFieldName+' like ''%'+dbo.Get_StrArrayStrOfIndex(@newWords,@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)
	--判断临时表是否存在,存在则删除,一定要删除!
	if OBJECT_ID('tempDb..##tempTable') is not null
	begin
		drop table ##tempTable
	end
END

调用方法基本不变(参数个数未变):

 

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

 

新特性说明:

 

         定义:把必须要出现的关键词用方括号[]括起来。例如[i]|o|c,则i在结果中必须出现。

         说明:假如需要匹配a、b、c三个关键词,重要性:a>b>c,那么可以这样写:a|b|c,这样已经保证a、b、c的权重依次降低,贪婪加权的算法基本可以保证:尽可能多的去匹配、尽可能匹配包含a的记录。但是某些时候为了提高准确性,要求结果中必须出现a,那么可以这样写:[a]|b|c。同理,必须出现a、b可以这样写:[a]|[b]|c。

         其他:此次更新加入了临时表技术,保证必要关键词指定效率。

 

 

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


  • 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、付费专栏及课程。

余额充值