MySQL Query - Searching for multiple keywords

Reply

Join Date: Oct 2009
Posts: 1
Reputation: aptitudedude is an unknown quantity at this point 
Solved Threads: 0
aptitudedude aptitudedude is offline Offline
Newbie Poster

MySQL Query - Searching for multiple keywords

 
0
  #1
25 Days Ago
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:

  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; 25 Days Ago at 7:35 pm. Reason: Keep It Organized - For easy readability, always wrap programming code within posts in [code] (code blocks)
Reply With Quote Quick reply to this message  
Join Date: Sep 2009
Posts: 6
Reputation: Calver is an unknown quantity at this point 
Solved Threads: 0
Calver Calver is offline Offline
Newbie Poster
 
0
  #2
25 Days Ago
Hello, I had a similar problem recently, and solved it like this...
  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.
Regards, John
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 431
Reputation: Atli is on a distinguished road 
Solved Threads: 55
Atli's Avatar
Atli Atli is offline Offline
Posting Pro in Training
 
0
  #3
24 Days Ago
You could also try using joins:
  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
Please do not ask for help in a PM. Use the forums.
And use [code] tags!
Reply With Quote Quick reply to this message  
Join Date: Sep 2009
Posts: 6
Reputation: Calver is an unknown quantity at this point 
Solved Threads: 0
Calver Calver is offline Offline
Newbie Poster
 
0
  #4
24 Days Ago
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.
Regards, John
Reply With Quote Quick reply to this message  
Join Date: Sep 2009
Posts: 6
Reputation: Calver is an unknown quantity at this point 
Solved Threads: 0
Calver Calver is offline Offline
Newbie Poster
 
0
  #5
24 Days Ago
Here's my effort (still fairly new to PHP) ...

  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. ?>
Regards, John
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 431
Reputation: Atli is on a distinguished road 
Solved Threads: 55
Atli's Avatar
Atli Atli is offline Offline
Posting Pro in Training
 
0
  #6
24 Days Ago
Ok, so I almost have this figured out.

  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.
  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:
  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; 24 Days Ago at 1:29 pm.
Please do not ask for help in a PM. Use the forums.
And use [code] tags!
Reply With Quote Quick reply to this message  
Reply

Tags
keyword, keywords, multiple, mysql, syntax

Message:



Other Threads in the MySQL Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC