Search Each Word Of a Search Using PHP MYSQL Search Query - php

I want to fetching Records On the Basis Of Entered Keywords in the Search Bar.
Suppose I have Below 3 Records in My SQL Table's Column
Beautiful Small Kid.
Beautiful Rabbit in the Zoo.
Natural Water.
Now, If the Search Query contains Beautiful, It will Return First 2 Records.
If the Search Query contains Beautiful (anything), It will Return Nothing.
I want those First 2 Records to be Displayed in this case too, Because It has the same word beautiful like in above searched Query.
Right Now, I am Using
SELECT * FROM table WHERE name LIKE '%value%' ORDER BY id ASC
Is there any Other Query or Method to Achieve Such Sort Of Results ?

SELECT * FROM table WHERE (name LIKE '%value1%') OR (name LIKE '%value2%') ORDER BY id ASC
etc
So, you would have to split up your search string into separate words.
$str = yourinput;
$strarray = (explode(" ",$str));
$query = "SELECT * FROM table WHERE ";
Foreach($strarray as $key=>$value){
If($key > 0){
$query = $query . "OR";
}
$query = $query . " (name LIKE '%" . $value . "%') ";
}
$query = $query . "ORDER BY id ASC";

Related

Creating a MYSQL query from results of splitting a string and using LIKE to match keywords in PHP

I am trying to split a string into an array and use these as keywords to make an sql query. I have made a sample of splitting the array and building the sql query. It sort of works but it is giving every table as a result but when I hard copy the built query it comes up with expected results.
This is what I have so far -
The string of keywords split into array and the query is built.
The db is called 'clients_personal' and the table is called 'likes'
$my_search = "paper, glue, discount, bulk";
$new_search = preg_split("/,/", $my_search);
$mmsql = "SELECT * FROM clients_personal WHERE likes LIKE '%offers%'";
foreach ($new_search as $value) {
$mmsql = $mmsql." OR likes LIKE '%$value%'";
}
No that results something like :
$mmsql="SELECT * FROM clients_personal WHERE likes LIKE '%offers%' OR likes LIKE '%paper%' OR likes LIKE '%glue%' OR likes LIKE '%discount%' OR likes LIKE '%bulk%'";
Now if I search like this, I get all the rows in the db?
$sql = "$mmsql";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$id=$row["id"];
echo $id;
}
}
But if I query is as hard coded it gives predicted results?
$sql = "SELECT * FROM clients_personal WHERE likes LIKE '%offers%' OR likes LIKE '%paper%' OR likes LIKE '%glue%' OR likes LIKE '%discount%' OR likes LIKE '%bulk%'";
$result = $conn->query($sql);
I have a feeling its to do with quotes and i have tried removing them but no good? Any advice?
Also I an using this type of search as I found it on here.
The problem is here $new_search = preg_split("/,/", $my_search); use $new_search = preg_split("/, /", $my_search); instead.
The items in the string are separated by a comma and a space (", ") so you should split the string with that.

What is the correct MySQL syntax to retrieve data with multiple parameters

I am retrieving data from a database with php and MySQL as follows
$query = mysql_query("SELECT * FROM pictures WHERE (title LIKE '%$Search%' OR keywords LIKE '%$Search%') AND approved = 'YES' ORDER BY title ASC");
The query is correct and there are no errors and the query works fine for "title LIKE '%$Search%'" but the parameter "OR keywords LIKE '%$Search%'" is not retrieving data. The parameter "AND" also works correctly.
The keywords are stored in the database for example "pizza, restaurants, take away" but I don't see that is a problem.
My question is "What is the correct syntax for applying the "OR" parameter?
Remove the brackets around (title LIKE '%$Search%' OR keywords LIKE '%$Search%')
Those are generally used for subqueries.
$query = mysql_query("
SELECT * FROM pictures
WHERE title LIKE '%$Search%'
OR keywords LIKE '%$Search%'
AND approved = 'YES'
ORDER BY title ASC
");
https://dev.mysql.com/doc/refman/5.0/en/subqueries.html
Here is an example of a subquery, and pulled from the manual on MySQL.com:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
Edit:
Or try a different quoting method:
$query = mysql_query("
SELECT * FROM pictures
WHERE title LIKE '".%$Search%."'
OR keywords LIKE '".%$Search%."'
AND approved = 'YES'
ORDER BY title ASC
");
You could also try escaping your data:
$Search = mysql_real_escape_string($Search);
as an example. I don't know how you're assigning that variable.
phpMyAdmin test edit:
This is what I used inside phpMyAdmin:
SELECT * FROM table
WHERE col1 LIKE '%pizza%'
OR col2 LIKE '%pizza%'
AND col3 = 'YES'
ORDER BY col1 ASC
using pizza as the search keyword seeing that $Search will be based on the same keyword for you, where columns contain "large pizza" in one, and "pizza, take away, restaurants" in another.
Remember that, whatever you're using/assigning $Search to, must reside inside all your queried columns.
You may also want to make use of explode().
Here is an example pulled from https://stackoverflow.com/a/15289777/
<?php
$search = 'Gold Chain Shirt';
$bits = explode(' ', $search);
$sql = "SELECT name FROM product WHERE name LIKE '%" . implode("%' OR name LIKE '%", $bits) . "%'";
The above will generate this query:
SELECT name FROM product WHERE name LIKE '%Gold%' OR name LIKE '%Chain%' OR name LIKE '%Shirt%'
Sorry for taking some time but this is my working answer to my own question... not the prettiest syntax but it works without any string functions or explode functions. MySql can handle keywords quite well without any other functions being included:
$query = mysql_query("SELECT * FROM pictures
WHERE
title LIKE '%$Search%' AND featured IS NOT NULL AND streetview IS NOT NULL AND (id_user > '1') AND (status = '1')
OR
keywords LIKE '%$Search%' AND featured IS NOT NULL AND streetview IS NOT NULL AND (id_user > '1') AND (status = '1') ORDER BY title ASC");
Thank you all for your contributions

IOS app , searchbox and SQL database

I have a SQL webhosting database with a table described as "Description". Now the database speaks with my app completely fine but I seem to have a issue regarding multiple keywords in a search. As of right now the search will only find the first word typed in the searchbox inside the table 'Description' in my databse. So say if my user types in "Dragon Tattoo" via the searchbox in the app, It will display everything with "Dragon" only.. In conclusion, what is the best method to have my search box list any keywords with multiple words with spaces for an exact match.
Here is my server side PHP for the search function:
function _search($text){
$dbObj=$this->CONN;
$query="SELECT * FROM tatoo_user_info where description LIKE '%$text%' OR name LIKE '%$text%' ORDER BY create_date DESC";
$stmt=$dbObj->prepare($query);
$res=$stmt->execute();
$rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
$resultant=array();
foreach($rows as $values){
$array=array();
$array=$values;
$query1="SELECT * FROM images where tui_id=:id";
$stmt1=$dbObj->prepare($query1);
$stmt1->bindParam(':id',$values['id']);
$res=$stmt1->execute();
$row=$stmt1->fetchAll(PDO::FETCH_ASSOC);
$arr_image=array();
foreach($row as $images){
$arr_image[]=$images['name'];
}
$resultant[]=array_merge($array,array("images"=>$arr_image));
}
//print_r($resultant);die;
if(count($resultant)>=1){
$result_a=array("status"=>"SUCCESS","message"=>"Successfully Fetched","data"=>$resultant);
echo json_encode($result_a);
}
else{
$result_a=array("status"=>"FAILURE","message"=>"Fail to find");
echo json_encode($result_a);
}
}
I am not sure about performance for this one but you can try with multiple queries:
$str = "Dragon Tattoo and much more";
$arr_words = explode(" ", $str);
foreach($arr_words as $word)
{
$word = trim($word);
$sql="SELECT * FROM tatoo_user_info where description LIKE '%$word%' OR name LIKE '%$word%' ORDER BY create_date DESC";
}
or you can build one long query:
foreach($arr_words as $word){
$sql .= " OR name LIKE '%$word%' and description LIKE '%$word%'... ";
}

Mysql LIKE clause and separate words in a field

I currently use a mysql statement like the one below to search post titles.
select * from table where title like %search_term%
But problem is, if the title were like: Acme launches 5 pound burger and a user searched for Acme, it'll return a result. But if a user searched for Acme burger or Acme 5 pound, it'll return nothing.
Is there a way to get it to return results when a users searches for more than one word? Is LIKE the correct thing to use here or is there something else that can be used?
You could use a REGEXP to match any of the words in your search string:
select *
from tbl
where
title REGEXP CONCAT('[[:<:]](', REPLACE('Acme burger', ' ', '|'), ')[[:>:]]')
Please notice that this will not be very efficient. See fiddle here.
If you need to match every word in your string, you could use a query like this:
select *
from tbl
where
title REGEXP CONCAT('[[:<:]]', REPLACE('Acme burger', ' ', '[[:>:]].*[[:<:]]'), '[[:>:]]')
Fiddle here. But words have to be in the correct order (es. 'Acme burger' will match, 'burger Acme' won't). There's a REGEXP to match every word in any order, but it is not supported by MySql, unless you install an UDF that supports Perl regexp.
To search for a string against a text collection use MATCH() and AGAINST()
SELECT * FROM table WHERE MATCH(title) AGAINST('+Acme burger*')
or why not RLIKE
SELECT * FROM table WHERE TITLE RLIKE 'Acme|burger'
or LIKE searching an array, to have a compilation of $keys
$keys=array('Acme','burger','pound');
$mysql = array('0');
foreach($keys as $key){
$mysql[] = 'title LIKE %'.$key.'%'
}
SELECT * FROM table WHERE '.implode(" OR ", $mysql)
What you need to do is construct a SQL such that, for example:
select * from table where title like "%Acme%" and title like "%burger%"
In short: split the string and create one like for each part.
It might also work with replacing spaces with %, but I'm not sure about that.
The best thing is thing use perform union operation by splitting your search string based on whitespaces,
FOR Acme 5 pound,
SELECT * FROM TABLE WHERE TITLE LIKE '%ACME 5 POUND%'
UNION
SELECT * FROM TABLE WHERE TITLE LIKE '%ACME%'
UNION
SELECT * FROM TABLE WHERE TITLE LIKE '%5%'
UNION
SELECT * FROM TABLE WHERE TITLE LIKE '%POUND%'
Find out a way to give the first query a priority. Or pass the above one as four separate queries with some priority. I think you are using front end tp pass query to data bases, so it should be easy for you.
<?php
$search_term = 'test1 test2 test3';
$keywords = explode(" ", preg_replace("/\s+/", " ", $search_term));
foreach($keywords as $keyword){
$wherelike[] = "title LIKE '%$keyword%' ";
}
$where = implode(" and ", $wherelike);
$query = "select * from table where $where";
echo $query;
//select * from table where title LIKE '%test1%' and title LIKE '%test2%' and title LIKE '%test3%'

Related video algorithm MySql using genre

I've looked around for info on an efficient 'related videos' algorithm but i'm struggling to get well ordered, accurate results
I get given the 'genre' as a pipe-delimited string. eg: |Action|Sci-Fi|Thriller|
$genre = explode("|", $row['genre']);
if (count($genre) == 3) {
$sql = "SELECT title FROM `movie` WHERE genre LIKE '%$genre[1]%' LIMIT 0,8";
} else {
$sql = "SELECT title FROM `movie` WHERE (genre LIKE '%$genre[1]%' AND genre LIKE '%$genre[2]%') UNION SELECT title FROM `movie` WHERE (genre LIKE '%$genre[1]%' OR genre LIKE '%$genre[2]%') LIMIT 0,10";
}
$related = mysql_query($sql);
Then I basically explode it and do a manual, inefficient search for genre matches depending on genre count. The results are poor and returns anything that is semi related.
This code makes me want to gag! It works but I hate it and I know its uber lame. Any tips to improve the SQL and getting richer results?
Move the mappings of genres to movies into a new table movie_genres with columns movie and genre.
This allows you to do this:
$genres = explode('|', trim($row['genre'], '|'));
$sql = "SELECT `movie`, COUNT(*) AS hits
FROM `movie_genres`
WHERE `genre` IN ('" . join("', '", $genres) . "')
GROUP BY `movie`
ORDER BY `hits` DESC
LIMIT 8";
You have to make sure to prevent SQL injection, though.
The extra table is also a good idea, because your database schema is not normalized. Especially Chris Date's fourth condition of the first normal form is violated:
Every row-and-column intersection contains exactly one value from the applicable domain (and nothing else).

Categories