`

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

阅读更多

原文转载自:http://blog.csdn.net/yangyuankp/article/details/8039990

 

在CMS开发中,经常会有类似这样的需求:
提问——回答模式,最经典的例子就是百度提问。
提问者提出问题,由其他人回答,其他人可以是用户,也可以是服务商。

在这个模式中,如何充分利用历史数据是最关键的技术。很多时候,由于客户不擅长使用搜索功能,一上来就提问,而这些问题往往早已经有近乎完美的答案,但没有充分利用。这样一来,不仅加大了劳动量,又增加了数据冗余。

如果在提问的时候能充分调动历史数据,提交问题之前先看看历史问题能不能解决客户疑问,解决了,最好不过,解决不了,再提交。百度提问就是采用的这种方案:

模式固然好,可怎么实现就有些困难了,毕竟这是百度作为搜索引擎的看家本领。

从上图可以看出“CSDN网站如何注册用户”这句话被拆成了N个词,然后分开去数据库中匹配,为什么?因为直接去匹配“CSDN网站如何注册用户”这句话,汉语博大精深,稍微变动一下:“如何在CSDN网站注册用户”,意思完全一样,但直接匹配绝对匹配不到!

因此,我们需要把一句话拆分成词组,这个在网上有现成的组件,比如“庖丁解牛”等,它们大多数是免费开源的。拆成词组之后,应该还要有一个关键词筛选词库,用这个词库确定出有效的词组,比如上图中,“CSDN”、“注册”、“用户”是有效的,而“网站”显然没有匹配,因为它在这句话中没有实际意义。

有点跑题了,拆词、选词不是本文的重点,但却是本文的前提。拿到关键词之后,怎么去数据库中匹配呢?

大家都知道T-SQL中的LIKE语句,通过类似LIKE “%abc%”这样的语法,可以进行模糊匹配,但是它仅仅能进行一次模糊匹配。举个例子:

假如我们确定了a,b,c三个关键词,要查找的记录当然是匹配的越多越好,于是可以这样写:LIKE “%a%b%c%”,这样匹配出的就是包含a,b,c三个关键词的记录,但是如果根本没有包含这三个关键词的记录,最多只有包含两个的,甚至是只包含一个,那么如何写LIKE语句呢?这样LIKE “%a%b%”?这样LIKE “%a%c%”?这样LIKE “%b%c%”?这样LIKE “%a%”?这样LIKE “%b%”?这样LIKE “%c%”?

 

显然,需要判断的情况太多,简单的LIKE语句已经无法满足需求。需要注意的是,千万不要试图选出范范的记录,返回到程序中去处理,在程序中处理虽然简单,但是范范的记录,在一个中型系统中,往往能达到千万级别,这么大的数据量,从数据库返回到程序,无疑会给服务器造成相当大的压力。

经过探索,本小菜总结了一个比较简单的方法,暂且称为“LIKE语句多条件贪婪匹配算法”。

算法思想:先用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  
	set @next=1
	while @next<=dbo.Get_StrArrayLength(@words,@splitString)
	begin
		--构造sql查询条件(中间部分)
		set @sqlCenter = @sqlCenter+'SELECT '+@primaryKeyName+' 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(*) AS showCout FROM ('
	--构造sql语句结尾部分
	set @sqlLast=') AS t_Temp GROUP BY '+@primaryKeyName+' ORDER BY showCout 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三个关键字,通过|分隔。

注意这个存储过程选出来的是匹配度高的记录的主键,还需要根据主键去表中查一下,查询出需要的内容(问题名称)。

  • 大小: 19.2 KB
分享到:
评论

相关推荐

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

    很多时候,由于客户不擅长使用搜索功能,一上来提问,而这些问题往往早已经有近乎完美的答案,但没有充分利用。这样一来,不仅加大了劳动量,又增加了数据冗余。  如果在提问的时候能充分调动历史数据,提交问题...

    sql模糊查询并按匹配度排序

    本篇文章将基于提供的SQL查询语句,详细介绍如何进行SQL模糊查询以及如何根据匹配程度对结果进行排序。 #### 一、SQL模糊查询基础 SQL中的模糊查询主要依赖于`LIKE`关键字来实现。`LIKE`允许使用通配符进行模式...

    SQL数据库模糊查询内容语句

    在SQL(Structured Query Language)中,模糊查询是一种非常重要的功能,它允许我们使用通配符来匹配不完全或不确定的数据。这种查询方式在处理大量数据时尤其有用,比如在搜索关键词、查找类似记录或者进行数据清洗...

    仿制简单的SQL select查询语句,用于对二维数组的查询,建立环境-Excel Vba,可移植到VB环境中

    ' 依条件设置查询数组,返回包含查询字段(或全部字段)的数组,可多条件组合。 ' 条件运算符包括:&gt; = &lt; &gt;= &lt;= &lt;&gt; , like(正则表达式) ' '附注: ' 使用此函数,需要在文件中引用正则表达式脚本 Microsoft VBScript...

    海量数据库的查询优化及分页算法方案 2 之 改良SQL语句

    4. Like语句是否属于SARG:Like语句是否属于SARG取决于所使用的通配符的类型,如:name like ‘张%' 属于SARG,而:name like ‘%张' 则不属于SARG。 5. OR 会引起全表扫描:使用OR会引起全表扫描,因为OR操作符会...

    SQL注入攻击检测算法研究.pdf

    本文档主要探讨了SQL注入攻击检测算法的研究,重点研究SQL注入攻击检测中的三个关键技术点:重构SQL语句、寻找注入点和猜测表名及字段名。SQL注入攻击是一种常见的网络攻击手段,它通过在Web表单输入或页面请求的...

    基于SQL查询语句的查询优化方法.pdf

    总之,查询优化是一项复杂的工作,需要开发者具备数据库系统、SQL语句以及索引管理等多方面的知识。通过合理的设计和优化,可以显著提高数据库系统的性能和响应速度,对于开发高效的数据库应用系统具有重要意义。

    php mysql like 实现多关键词搜索的方法

    从内容中提供的示例来看,直接使用AND连接两个LIKE语句是错误的,如下所示: ```sql $res=mysql_query("select * from peter where id like '%中草药%' and '%6%'"); // 这样写是报错的; ``` 这里的错误在于AND...

    DB2_SQL优化.doc

    * 其他注意小点:可以通过优化 SQL 语句的结构和算法来提高性能。 如何建立合理的索引 建立合理的索引可以加速 SQL 语句的执行。以下是一些建立索引的方法: * 建立唯一索引:可以使用 Unique 语句来建立唯一索引...

    SQL Server数据库查询语句优化的研究.pdf

    使用以通配符"%"开头的LIKE语句会导致SQL Server无法使用索引,从而降低查询速度。应尽量避免此类语句,或者将"%"置于查询条件的末尾。 4.1.3 避免使用负逻辑 负逻辑操作符如"!=", "NOT EXISTS", "NOT IN"会导致...

    mysql_海量数据库的查询优化及分页算法方案.doc

    本文详细介绍了 MySQL 海量数据库的查询优化和分页算法方案,包括查询优化的原理、SARG 的定义和形式、非 SARG 形式的语句、分页算法等。通过这些方法,可以提高 MySQL 海量数据库的查询效率和性能。

    PHP+Mysql实现多关键字与多字段生成SQL语句的函数

    本示例介绍了一个PHP函数,该函数可以帮助我们根据输入的关键字和字段生成对应的SQL WHERE子句,从而实现多条件查询。 函数名为`search()`, 接收三个参数: 1. `$keyword`:这是一个包含多个关键字的字符串,...

    基于SQL-Like语言的分布式推荐系统.pdf

    本文所提出的基于SQL-Like语言的分布式推荐系统,利用了Apache Pig的轻量级开发方式和Hadoop的分布式处理能力,结合了Item-Based协同过滤算法的高效性,为大数据环境下的推荐系统提供了一个可维护性和轻量级开发的...

    算法面试题大全.txt

    根据提供的文件信息,我们可以归纳出该文档主要围绕SQL查询语句在算法面试中的应用与技巧进行阐述。下面将从几个方面来深入解析这些知识点: ### 1. SQL基础查询 #### 1.1 SELECT语句的基本用法 - **全选(`SELECT...

    SQL数据的查询和更新实验报告报告.pdf

    - (4)`SELECT CourseNo FROM Courses WHERE CourseName LIKE '%算法%';` - (5)`SELECT DISTINCT CourseNo FROM Reports;` - ...(其他步骤类似,涉及聚合函数,连接查询,子查询等) ### 4. 实验要求 实验要求...

    sql优化、索引的建立和运用以及多表连接建索引的拙劣见解

    ### SQL优化、索引的建立和运用以及多表连接建索引的相关知识点 #### SQL优化概述 在数据库系统中,SQL语句的执行效率对于系统的响应时间和资源利用有着至关重要的影响。合理的SQL优化不仅可以显著提升查询速度,还...

    sql语句技巧

    ### SQL语句技巧详解 #### 一、减少数据库访问与优化查询 1. **减少数据库访问次数**:在设计应用程序时,应该确保在满足业务需求的前提下,尽量减少对数据库的直接访问。例如,可以通过缓存机制来缓存常用的数据...

    T-SQL查询技巧语句(收藏版).txt

    ### T-SQL 查询技巧语句详解 #### 一、按笔画排序查询 **知识点:** 1. **语法格式:** ```sql SELECT * FROM TableName ORDER BY CustomerName COLLATE Chinese_PRC_Stroke_ci_as; ``` 2. **解释:** - `...

    数据库优化查询总结,主要是sql语句

    4. **避免复杂的正则表达式**:使用`MATCHES`或`LIKE`关键字支持的正则表达式虽然功能强大,但其处理过程非常耗时。如果可能,应尽量避免使用复杂的正则表达式,并考虑使用更简单的条件替代。 5. **使用临时表加速...

Global site tag (gtag.js) - Google Analytics