Here is a solution using recursive CTEs. It actually uses two separate recursions. The first breaks the lines into tokens, and the second recursively filters the records using each token.
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)
It took me about 15 seconds to search for a table of 10 thousand records for the search string "this is a test field" .. (the more words in the string, the longer it takes.)
Edit
If you want a fuzzy search to return closely comparable results, even if there was no exact match, you could change the last line in the query -
select * from (select max(ind) as ind, myfield from filter group by myfield) t order by ind desc
'ind' will give you the number of words from the search bar found in my field.
source share