sql LIKE does not show wanted results to fetch - php

For an related products part I'm making it does not show the results I want it to show.
This is my code:
// Info current t-shirt. Normally from database
$name = "T-shirt";
$description = "Stylish LUFTRAUSERS T-shirt designed by Amon26.";
$relatedSearch = $name . " " . $description;
// Query which searches for related items
$query = $db->prepare("SELECT * FROM tbl_products WHERE description LIKE '%' :relatedSearch '%' OR name LIKE '%' :relatedSearch '%' LIMIT 5");
$query -> bindParam("relatedSearch", $relatedSearch, PDO::PARAM_STR);
if($query -> execute()){
while($related = $query->fetch(PDO::FETCH_OBJ)) {
echo "<p style='color:black;'>" . $related->description . "</p></br>";
}
}
When I replace the bindparam $relatedSearch for $name it does show 5 results. But when I search for $relatedSearch variable it doesn't show anything. It seems that it searches for the full string and nothing matches that. Instead of that I just want it to look for single words in that string
Extra: Screenshot of the database http://puu.sh/eeviJ/133a2de7c9.png

You need to include the colon in your binding. I would also try structuring your query like this instead.
$query = $db->prepare("SELECT * FROM tbl_products
WHERE description
LIKE :relatedSearch OR name LIKE :relatedSearch LIMIT 5");
$query -> bindParam(":relatedSearch", '%' . $relatedSearch . '%', PDO::PARAM_STR);
But, maybe this is more like what you're looking for...
$query = $db->prepare("SELECT * FROM tbl_products
WHERE description
LIKE :description OR name LIKE :name LIMIT 5");
$query -> bindParam(":description", '%' . $description . '%', PDO::PARAM_STR);
$query -> bindParam(":name", '%' . $name . '%', PDO::PARAM_STR);

Maybe it is usefull for you.
Do not use single quote after %.
$query = $db->prepare("SELECT * FROM tbl_products WHERE description LIKE '% :relatedSearch %' OR name LIKE '% :relatedSearch %' LIMIT 5");

Related

select where like with an array

$tag = 'sky';
select rows where tags contains $tag:
$sql = "select * from images where tags like '%" . $tag . "%' order by date desc";
What if I have an array of tags:
$tags = array('sky', 'earth', 'sun'); // max 3
foreach($tags as $tag) {
$sql = "select * from images where tags like '%" . $tag . "%' order by date desc";
}
Is this the right way, especially regarding performances.
The table images has about 20.000 rows.
You can use regexp.
$sql = "select * from images where tags REGEXP '" . implode('|', $tags) . "' order by date desc";
Your final result will be:
select * from images where tags REGEXP 'sky|earth|sun' order by date desc
Here is a possible implementation, you don't have to know the array size.
$tags = array('one', 'two');
$sql = "select * from images where tags like '%" . implode("%' OR tags like '%",$tags) . "%' order by date desc";
Add multiple tags to your query using OR in your query
$sql = "select * from images where tags like '%" . $tag[0] . "%' OR tags like '%" . $tag[1] . "%' OR tags like '%" . $tag[2] . "%' order by date desc";
You don't need to use foreach to run query
UPDATE 1
$comma_separated = "('" . implode("','", $tags) . "')";
$sql = "select * from images where tags IN ".$comma_separated;
Most Efficient Way
A REGEXP might be more efficient, you have to benchmark it by your self
$sql = "select * from images where tags REGEXP '" . implode('|', $tags) . "' order by date desc";

Is it possible to search all columns through MySQL table in PHP query, without typing out each column name?

I am asking this because I am looking for a PHP query for MySQL like the following:
SELECT * FROM users WHERE ALL_COLUMNS LIKE '%" . $search . "%'
Does a query like this exist? Or do I have to type the query like so:
SELECT * FROM users
WHERE
user_email LIKE '%" . $search. "%'
OR user_name LIKE '%" . $search. "%'
OR first_name LIKE '%" . $search. "%' OR [...]
Note that you can probably achieve something like this in your favorite mysql frontend, I use sqlyog and you can do that with the "data search" tool, I'm sure other software like mysql workbench has a similar option.
Anyway, you can have php construct the query for you. Get all of the columns into an array by querying information_schema, and then make a string with each columns name like
"columnName LIKE '%$search%'"
and then implode it on " OR ", like this:
//what is the search?
$search = "something";
//get all the columns
$columns = mysqli_query("SELECT
COLUMN_NAME
FROM
information_schema.COLUMNS
WHERE TABLE_NAME = 'users'
AND TABLE_SCHEMA = 'yourDatabaseName' ");
//put each like clause in an array
$queryLikes = array();
while ($column = mysqli_fetch_assoc($columns)) {
$queryLikes[] = $column['COLUMN_NAME'] . " LIKE '%$search%'";
}
$query = "SELECT * FROM users WHERE " . implode(" OR ", $queryLikes);
echo $query; //should look like this:
//SELECT * FROM users WHERE column1 LIKE '%something%' OR column2 LIKE '%something%' OR column3 LIKE '%something%' OR ...
//so then
$users=mysqli_query($query);
while ($user = mysqli_fetch_assoc($users)) {
//do stuff with $user
}
It's quite simple:
Just iterate through all columns in your table and check them for the value you want.
This example searches column titled "column"
$qry= mysql_query("select * from $tblName order by id");
while($row = mysql_fetch_assoc($qry)){
if($searchItem == $row['column']){
echo "Match found!";
break;
}
}

Wordpress: wpdb prepare with conditional variable

I currently have a table. If the user searches for something, I would like the query to return the filtered results. If the user doesn't search for something, it should return all results. I'm not too sure how to do this with wpdb prepare.
if($search_query!=="all") {
$search_query = '%' . $search_query . '%';
$where = 'WHERE column_name LIKE %s';
}
$results = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}table_name ".$where." ORDER BY id DESC LIMIT %d, %d", $search_query,$current_page,$rows_per_page));
Right now nothing returns when the search field is empty because the query is erroring out because it's throwing the parametrization off and passing $search_query to the %d beside LIMIT. Is it possible to make this variable conditional? Is there a way to do this without an IF statement ?
It looks like you can pass an array to prepare, as well as a list of variables, according to the WordPress documentation
That means that you could do something like this:
$where = "";
$parameters = array($search_query,$current_page,$rows_per_page);
if($search_query!=="all") {
array_push($parameters, '%' . $search_query . '%');
$where = 'WHERE column_name LIKE %s';
}
$results = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}table_name ".$where." ORDER BY id DESC LIMIT %d, %d", $parameters));
Your WHERE clause will be empty if there's no data, so concatenating it into your query won't cause issues.
Why not do the prepare in the "If" statement? You can then do the other prepare (without the where clause) in the "Else" and just use the get_results on the proper prepared query?
if($search_query!=="all") {
$search_query = '%' . $search_query . '%';
$where = 'WHERE column_name LIKE %s';
$prepared = $wpdb->prepare("SELECT * FROM {$wpdb->prefix}table_name ".$where." ORDER BY id DESC LIMIT %d, %d", $search_query, $current_page, $rows_per_page) ;
} else {
$prepared = $wpdb->prepare("SELECT * FROM {$wpdb->prefix}table_name ORDER BY id DESC LIMIT %d, %d", $current_page, $rows_per_page);
}
$results = $wpdb->get_results($prepared);
You can escape the like parameter yourself and add it as a where clause if needed like this:
function like($str)
{
global $wpdb;
return "'" . '%' . esc_sql($wpdb->esc_like($str)) . '%' . "'";
}
if($search_query!=="all") {
$where = 'WHERE column_name LIKE ' . like($search_query);
}
and remove the search_query param from the prepared statement

LIKE query is unable to retrieve data, why?

This query is unable to retrieve any data from MySQL for reasons I cannot figure out after countless hours..
public function search()
{
if(isset($_GET['search']))
{
$searchTerms = trim(strip_tags($_GET['search']));
$sth = $this->db->prepare("SELECT COUNT(*) FROM articles WHERE (article_content LIKE :search) OR (article_title LIKE :search)");
$sth->execute( array(':search' => '%' . $searchTerms . '%') );
if($sth->fetchColumn() > 0)
{
while($row = $sth->fetchAll(PDO::FETCH_ASSOC))
{
return "search results: " . $row['article_title'];
return "" . $row['article_content'];
}
} else {
echo "No results.";
}
}
}
No matter what keyword I type in the form it always returns "No results.". What could be the issue because from what I can see it should work..
Selecting all rows from the table structure and counting so that fetchColumn can be runned, it is selecting from the correct table (articles), where article_content and article_title are both rows in the table, so what is the issue?
$sth->execute(array(':search' => '%'.$searchTerms.'%'));
Should be:
$sth->execute(array(':search' => '\'%\' + \''.$searchTerms.'\' + \'%\''));
Each bind var needs to be an individual bind var, even when named, and even when they both contain the same value:
$sth = $this->db->prepare(
"SELECT COUNT(*)
FROM articles
WHERE (article_content LIKE :search1)
OR (article_title LIKE :search2)"
);
$sth->execute(
array(
':search1' => '%' . $searchTerms . '%',
':search2' => '%' . $searchTerms . '%'
)
);
Try this:
$sth = $this->db->prepare("SELECT COUNT(*) FROM articles WHERE (article_content LIKE :search0) OR (article_title LIKE :search1)");
$searchstring="%" . $searchTerms . "%";
$sth->execute( array(':search0' =>$searchstring ,':search1'=>$searchstring) );
pdo fails to retrieve values when the same placheholder is repeated in a query with LIKE in it.

PHP MySQL Search Combined Columns

I had just finished my search functionality for a users system when I found out that it didn't search the way I wanted it to.
If I have a datebase table with 2 columns called 'fname' and 'lname'.
In one row, 'fname' has a value of 'Ashley' and 'lname' has a value of 'Staggs'.
I can search for either 'Ashley' or 'Staggs' and I will get the results correctly, but if I search for 'Ashley Staggs', no results are displayed.
How would I do this properly?
My SELECT query is as follows:
SELECT * FROM `users` WHERE fname LIKE '%" . protect($_GET['s']) . "%' OR lname LIKE '%" . protect($_GET['s']) . "%'
I knew something like this would happen, but this time I can't figure it out.
Thanks,
Ashley
'Ashley Staggs' is neither in fname, nor in lname, so your request doesn't return anything. You could try to concatenate your MySQL fields:
SELECT * FROM `users` WHERE fname LIKE '%" . $_GET['s'] . "%' OR lname LIKE '%" . $_GET['s'] . "%' OR CONCAT(fname, ' ', lname) LIKE '%" . $_GET['s'] . "%'
[EDIT] Even better:
SELECT * FROM `users`
WHERE REPLACE(CONCAT(fname, lname, fname), ' ', '')
LIKE '%" . str_replace(' ', '', protect($_GET['s'])) . "%'
SELECT fname_lname FROM ( SELECT CONCAT(fname, ' ', lname) fname_lname FROM users ) users
WHERE fname_lname LIKE '%" . $_GET['s'] . "%'
You might try something like this - it'll just split the search string by spaces and search for each word:
$search = explode(' ', $_GET['s']);
$query = 'SELECT * FROM `users` WHERE 0';
foreach ($search as $v)
{
$v = mysql_real_escape_string($v);
$query .= " OR (`fname` LIKE '%{$v}%' OR `lname` LIKE '%{$v}%')";
}
// echo $query;
Regarding sp00m answer, I have a slightly different approach, but built on the same concept.
$search = preg_replace ( "/\s\s+/" , " " , $_GET['s']);
And then use this query:
"SELECT * FROM `users` WHERE CONCAT(fname, ' ', lname) LIKE '%" . $search . "%' OR CONCAT(lname, ' ', fname) LIKE '%" . $search . "%'"
EDIT
Just had an idea you could use. Basically, you could create two additional fields in the table - fname_lname and lname_fname , use the regex I mentioned before to get rid of unnecessary spaces, use explode() to check the word count. If you have two words, then you can use these two new fields, giving you only two conditions in the query. When you have only one word, you still have two conditions in the query.
hey i want to sugest a stronger more strong search but it required MyISAM table
code for this is
$q="you search string";
$searchArray = explode(" ", $q);
$query="SELECT * FROM cmusers WHERE MATCH (`firstname`, `lastname`, `email`) AGAINST ('";
$i=0;
foreach ($searchArray as $word) {
$query .= "+".$word."* ";
}
$query .= "' IN BOOLEAN MODE)";
$result=mysql_query($query) or die("Error founded:".mysql_error()."there is problem existing we feels a very great sorry");
$finded=mysql_num_rows($result);
working of this can be seen at http://www.funnenjoy.com
I will just do
SELECT * FROM users WHERE CONCAT(firstname, ' ', lastname) LIKE '%{$search}%'

Categories