views:

57

answers:

3

I currently have a SQL query that returns results based on a dynamic number of keywords passed in.

I convert the list of keywords into a table and join to it.

    SELECT * FROM Table1
    INNER JOIN
        dbo.udf_List2Table(@Keywords, ',') ON (Field1 LIKE '%'+Keyword+'%')

This is working fine but it returns all rows that contain any of the keywords that are suppiled. What I would like to do is return all rows that contain all of the keywords supplied.

I'm pretty sure you can't do this using a JOIN. Does anyone have any suggestions on how I could do this? I'm trying to avoid dynamic SQL.

Thanks

+1  A: 

Try

SELECT Field1 FROM Table1
INNER JOIN
    dbo.udf_List2Table(@Keywords, ',') ON (Field1 LIKE '%'+Keyword+'%')
GROUP BY Field1
HAVING COUNT(Keyword) = n

to match n keywords

Jon Freedman
+1  A: 
SELECT  *
FROM    Table1
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    dbo.udf_List2Table(@Keywords, ',')
        WHERE   field1 NOT LIKE '%' + Keyword + '%'
        )

This can be done more efficiently if you create a FULLTEXT index on field1 and make your @Keywords doublequote enclosed and AND separated:

SET @Keywords = '"cabbages" AND "kings"'
SELECT  *
FROM    table1
WHERE   CONTAINS(Field1, @Keywords)
Quassnoi
This is prone to sql injection, if you search for the keyword `''); DROP TABLE table1;--`
Jon Freedman
@Jon, I think it is simply an example using a variable and a string literal to illustrate the syntax. In the real world i suspect @Keywords would be a parameter in a stored procedure which would not be vulnerable to SQL injection.
Ben Robinson
@Jon: no, this is not, as long as you pass the Keyword in a bound parameter.
Quassnoi
@Quassnoi, the NOT EXISTS statement returns perfect results, thanks. I agree that a FULLTEXT index would work better but at the moment I don't have rights to create one.@Jon, you're answer also worked well. I've opted for this approach though but thank you.
Jamie
A: 

May be you can do following tweak.

DECLARE @recordcount int
SELECT @recordcount = count(1) from dbo.udf_List2Table(@Keywords, ',')
select t1.Field1
from Table1 t1
where @recordcount = (select count(1) from dbo.udf_List2Table(@Keywords, ',') k where t1.Field1 like '%' + k.Keyword + '%')
Anil