944,110 Members | Top Members by Rank

Ad:
  • MySQL Discussion Thread
  • Unsolved
  • Views: 3107
  • MySQL RSS
Oct 30th, 2009
0

MySQL Query - Searching for multiple keywords

Expand Post »
Hello,

I have a two tables created to apply keywords to a given entry:

Table: File
FileID (int, pk, auto incr)
Name (varchar)

Table File_Keyword
KeywordID (int, pk, auto incr)
FileID (fk)
Keyword (varchar)


Given that I have a record in table File with 2 corresponding records in table File_Keyword assigning keywords "ABC" and "XYZ" to the given FileID.

What is a simple sql query to only return results if both strings are matched:

sql Syntax (Toggle Plain Text)
  1. SELECT file.FileID WHERE file.FileID=file_keyword.FileID AND (file_keyword.Keyword LIKE '%ABC%' AND file_keyword.Keyword LIKE '%XYZ%');


Any assistance would be appreciated.

Thank you in advance.
Last edited by peter_budo; Oct 30th, 2009 at 7:35 pm. Reason: Keep It Organized - For easy readability, always wrap programming code within posts in [code] (code blocks)
Reputation Points: 10
Solved Threads: 0
Newbie Poster
aptitudedude is offline Offline
1 posts
since Oct 2009
Oct 30th, 2009
0
Re: MySQL Query - Searching for multiple keywords
Hello, I had a similar problem recently, and solved it like this...
MySQL Syntax (Toggle Plain Text)
  1. SELECT A.FileID, A.Name FROM file AS A
  2. WHERE EXISTS ( SELECT B.FileID FROM file_keyword AS B
  3. WHERE A.FileID = B.FileID AND B.Keyword LIKE '%ABC%'
  4. AND EXISTS ( SELECT B.FileID FROM file_keyword AS B
  5. WHERE A.FileID = B.FileID AND B.Keyword LIKE '%XYZ%'
  6. ))
I still don't know if there's an easier way to do it.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Calver is offline Offline
6 posts
since Sep 2009
Oct 31st, 2009
0
Re: MySQL Query - Searching for multiple keywords
You could also try using joins:
sql Syntax (Toggle Plain Text)
  1. SELECT f.FileID, f.Name
  2. FROM `File` AS f
  3. INNER JOIN `File_Keyword` AS fk1
  4. ON f.`FileID` = fk1.`FileID`
  5. AND fk1.`Keyword` LIKE '%key1%'
  6. INNER JOIN `File_Keyword` AS fk2
  7. ON f.`FileID` = fk2.`FileID`
  8. AND fk2.`Keyword` LIKE '%key2%'

There must be a more dynamic way tho. A way to check multiple keywords without hard-coding in a sub-query or a join for each of them.

Damn... now I won't be able to think about anything else until I find it xD
Reputation Points: 93
Solved Threads: 70
Posting Pro
Atli is offline Offline
526 posts
since May 2007
Oct 31st, 2009
0
Re: MySQL Query - Searching for multiple keywords
I never thought about joining the same table more than once. I think I can use that

It should be fairly straightforward to build the querystring with an array of search terms and a foreach loop through the array.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Calver is offline Offline
6 posts
since Sep 2009
Oct 31st, 2009
0
Re: MySQL Query - Searching for multiple keywords
Here's my effort (still fairly new to PHP) ...

MySQL Syntax (Toggle Plain Text)
  1. <?php
  2. $searches = array ("saloon", "diesel", "blue");
  3. $fileID = 123;
  4. $count = 0;
  5. $alias = "";
  6. $sql = "SELECT f.FileID, f.Name FROM `File` AS f ";
  7. foreach ($searches as $search) {
  8. $count ++;
  9. $alias = "fk".$count;
  10. $sql .= "INNER JOIN `File_Keyword` AS ".$alias
  11. ." ON f.`FileID` = ".$alias.".`FileID`
  12. AND ".$alias.".`Keyword` LIKE '%".$search."%' ";
  13. }
  14. $sql .= "WHERE f.`FileID` = ".$fileID;
  15. echo ($sql);
  16. ?>
Reputation Points: 10
Solved Threads: 0
Newbie Poster
Calver is offline Offline
6 posts
since Sep 2009
Oct 31st, 2009
0
Re: MySQL Query - Searching for multiple keywords
Ok, so I almost have this figured out.

sql Syntax (Toggle Plain Text)
  1. SELECT f.`file_id`, f.`name`
  2. FROM `file` AS f
  3. WHERE f.`file_id` NOT IN(
  4. SELECT fi.`file_id`
  5. FROM `file` AS fi
  6. INNER JOIN `file_keyword` AS fki
  7. ON fi.`file_id` = fki.`file_id`
  8. WHERE fki.`keyword` NOT IN('first', 'second', 'third')
  9. );
There you can just list the keywords in the last NOT IN clause.
php Syntax (Toggle Plain Text)
  1. $keywords = array ("first", "second", "third");
  2. $keyword_list = implode(", ", $keywords);
  3.  
  4. $sql = <<<SQL
  5. SELECT f.`file_id`, f.`name`
  6. FROM `file` AS f
  7. WHERE f.`file_id` NOT IN(
  8. SELECT fi.`file_id`
  9. FROM `file` AS fi
  10. INNER JOIN `file_keyword` AS fki
  11. ON fi.`file_id` = fki.`file_id`
  12. WHERE fki.`keyword` NOT IN({$keyword_list})
  13. );
  14. SQL;
  15.  
  16. echo $sql;

Only problem is, this returns files where all of it's keywords are in the list, but it doesn't have to match every keyword in the list.
For example, if I have created these rows:
sql Syntax (Toggle Plain Text)
  1. INSERT INTO `file`(`name`) VALUES ('File1'), ('File2');
  2.  
  3. INSERT INTO `file_keyword`(`file_id`, `keyword`)
  4. VALUES
  5. (1, 'first'), (1, 'second'),
  6. (2, 'third'), (2, 'fourth');
Running the above query, it would return 'File1', even tho it only matches two out of three keywords.
Last edited by Atli; Oct 31st, 2009 at 1:29 pm.
Reputation Points: 93
Solved Threads: 70
Posting Pro
Atli is offline Offline
526 posts
since May 2007

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in MySQL Forum Timeline: Problems restoring mysql database backups
Next Thread in MySQL Forum Timeline: Stored Procedures Help please





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC