这是一个使用递归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记录的表搜索字符串“这是一个测试场”。(字符串中的更多的话,它需要较长的..)
编辑
如果你想有一个模糊搜索,即返回密切匹配的结果,即使有wasnt完全匹配,你可以修改的最后一行的查询是 -
select * from (select max(ind) as ind, myfield from filter group by myfield) t order by ind desc
“IND”禾uld给你从myfield中找到的搜索字符串中的单词数量。
这只会返回具有与参数 – 2010-11-18 14:55:56
好主意(+1)相同顺序的搜索词的那些行,只要确保所有单词之间有足够空间。 – 2010-11-18 14:57:47