搜索包含另一个字符串中所有单词的varchar字段

时间:2010-11-18 14:37:22

标签: sql-server tsql sql-server-2008

尝试执行小型存储过程而无需为此添加自由文本索引(SQL Server 2008)

基本上,我想查找某个字段包含参数中所有单词的所有记录。

因此,如果在该字段中我有“这是一个测试字段”,并且我的SP的参数将是“此测试字段”,它将返回它,就像参数是“字段此测试”一样。 / p>

表非常小(4000)记录和负载会很低,因此效率不是什么大问题。现在,我能想到的唯一解决方案是将具有表值函数的两个字符串拆分并从那里开始。

任何更简单的想法?

谢谢!

2 个答案:

答案 0 :(得分:2)

效率不是一个大问题,为什么不用一点动态SQL。类似的东西:

create procedure myproc (@var varchar(100))
as
set @var = '%' + replace(@var, ' ', '%') + '%'
exec ('select * from mytable where myfield like '''+ @var + '''')

答案 1 :(得分:1)

这是使用递归CTE的解决方案。这实际上使用两个单独的递归。第一个将字符串拆分为标记,第二个使用每个标记递归过滤记录。

declare     
    @searchString varchar(max),
    @delimiter char;

select 
@searchString  = 'This is a test field'
,@delimiter = ' '

declare @tokens table(pos int, string varchar(max))

 ;WITH Tokens(pos, start, stop) AS (
      SELECT 1, 1, CONVERT(int, CHARINDEX(@delimiter, @searchString))
      UNION ALL
      SELECT pos + 1, stop + 1, CONVERT(int, CHARINDEX(@delimiter, @searchString, stop + 1))
      FROM Tokens
      WHERE stop > 0
    )
    INSERT INTO @tokens
    SELECT pos,
      SUBSTRING(@searchString, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS string
    FROM Tokens
    OPTION (MAXRECURSION 25000) ;

;with filter(ind, myfield) as (
    select  1,myfield from mytable where myfield like '%'+(select string from @tokens where pos = 1)+'%'    
    union all
    select  ind + 1, myfield from filter where myfield like '%'+(select string from @tokens where pos = ind + 1)+'%'    
    )

    select * from filter where ind = (select COUNT(1) from @tokens)

我花了大约15秒来搜索10k记录表中的搜索字符串&#39;这是一个测试字段&#39; ..(字符串中的单词越多,所需的时间越长......)< / p>

修改
如果你想进行模糊搜索,即使没有完全匹配,也会返回非常匹配的结果,你可以修改查询中的最后一行 -
select * from (select max(ind) as ind, myfield from filter group by myfield) t order by ind desc

&#39; IND&#39;会给你在myfield中找到的搜索字符串中的单词数。