views:

79

answers:

2

I'm using MS SQL 2008 and I'm facing a challenge for a few day's now. My SP parameter can contain one to three words in a string (nvarchar) and I have to return matching LIKE %phrase% records for each word in a string.

Example. My parameter is:

"stack overflow"

Records that must be returnd:

miSTACKon
noOVERFLOWon
STACKit
poOWERFLOW
STACK
OWERFLOW

I also considered FTS but CONTAINS function takes only one wildcard at the end of the (each) phrase

phrase*

Is there a solution to this problem other than dynamic SQL?

A: 

You could pass the 'words' with a fixed delimiter character (i.e. ',', '|', etc.) that isn't otherwise needed for any possible 'words' (that you're supporting), then parse that argument with a table-valued function, and finally join the set of words with a JOIN condition similar to LIKE '%' + word + '%'.

Kenny Evitt
+5  A: 

Start with the generic example and then i will mock it up with some "union alls"

   select distinct Record from dbo.Records
     inner join dbo.Split('stack overflow', ' ') tokens 
       on records_table.Record like '%' + tokens.value + '%'

So what I did below is i mocked some data that are the "records, as well as a mock return from the dbo.Split function, basically a table of varchars with 'stack' and 'overflow' tokenized on ' ' .

select distinct Name from (
 select 'stack' as Name
 union all
 select 'nope' as Name
 union all
 select ' stackoverflow' as Name
   ) records_table 
   inner join (
   select 'stack' as value
     union all
    select 'overflow' as value) tokens 
    on records_table.Name like '%' + tokens.value + '%'

Results:

stack
stackoverflow

There is nothing special about the dbo.Split function and there are tons of implementation examples out there...

Nix
My personal favorite split function is [here](http://www.mssqltips.com/tip.asp?tip=1665).
Joe Stefanelli
This actually solves bigger part of my problem. Thank you for this. Do you have an idea how would i sort results by relevance? I'm thinking like from perfect match(es) downwards. I guess my Split function would have to take care of that somehow...
Leon
what do u mean relevance? You could return a table with the "split" value and a ranking? and then order by that. Elaborate a little more and i will put some thought into it.
Nix
Not ranking as in FTS. I was thinking sorting results in a way that exact matches of parameter word(s) followed by partial matches with one character difference (if any), than two and so on. What i do right now, by using your solution, first i join with "=" and in second identical query i join with "LIKE" and at the end UNION of two results set. This way i get exact matches (if any) at the beginning of the results set followed by other matches selected by LIKE. This approach does the job (at least the important part) but it seems dirty to me.
Leon