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}%'
Related
I am trying to use SQL LIKE for two different column. Is it possible to use this type of operation?
I have already tried like :
$sWhere .= " file_name like '%" . $search_item . "%' OR name like '%" . $search_item . "%' and ";
But above code is only working for single case . i want to perform search for both.
this is my code:
if (isset($search_item) && $search_item != '') {
$sWhere .= " file_name like '%" . $search_item . "%' and ";
}
I want to perform search operation using both the column name with one search field.
Response :
SELECT a.id, a.file_name, a.file_path,a.upload_type,a.upload_by, b.username,a.addedon
FROM tbl_asd as a
INNER JOIN user as b on b.id = a.upload_by
WHERE a.upload_type = 'asd' and a.addedon >= ( CURDATE() - INTERVAL 1000 DAY ) and (file_name like '%asd%' OR upload_by like '%asd%') ORDER BY id desc limit 0,10
With "No Rows" Found!
Guide me!
Thanks!
You need to enclose the OR part of your WHERE clause in parentheses, otherwise you will get more results than you expect (basically any row which has file_name like '%" . $search_item . "%'). Use this instead:
$sWhere .= " (file_name like '%" . $search_item . "%' OR name like '%" . $search_item . "%') and ";
Note that your query as is can leave you open to SQL injection. Ideally you should be preparing a query instead using code similar to this:
$query = "SELECT ... FROM ... WHERE";
$params = array();
$types = '';
if (isset($search_item) && $search_item != '') {
$query .= " file_name like ? OR name like ? AND ";
$types .= 'ss';
array_push($params, "'%$search_item%'", "'%$search_item%'");
}
// add other where clauses in a similar way
// ...
// make sure we have a trailing `WHERE` clause
$query .= '1 = 1';
$stmt = $link->prepare($link, $query) or die($link->error);
$stmt->bind_param($types, ...$params);
$stmt->execute() or die($stmt->error);
$sWhere .= " (file_name like '%" . $search_item . "%' OR name like '%" . $search_item . "%') and ";
You could use concat for build the proper like condition
$sWhere .= " file_name like concat('%', $search_item ,'%') OR name like concat('%', $search_item ,'%') ";
(removed the AND at the end of the string)
Anyway you should take a look at your db driver for prepared statmenent and binding param because the use of PHP in SQL could produce SqlInjection
$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";
I just want to input mobile_no1 and mobile_no2 and want to search in mobile_no.
I have a table with mobileno, cusname, etc,
I want to search mobile number by giving first and last digits of mobile number.
How?
$table_name ='search1_ts1';
if(isset($_POST['tablename']) && !empty($_POST['tablename'])){
$table_name =$_POST['tablename'];
}
$search_query='SELECT mobile_no, fname, cus_name '.
'FROM $table_name '.
"WHERE mobile_no LIKE 'mobile_no1%' ".
"AND mobile_no LIKE '%mobile_no2'";
$conditionsql="";
if(isset($_POST['mobile_no1'], $_POST['mobile_no2']) &&
!empty($_POST['mobile_no1'])) {
$conditionsql.=" mobile_no1 like '%" . $_POST['mobile_no1'] . "%'";
}
if(isset($_POST['mobile_no2']) && !empty($_POST['mobile_no2'])){
$conditionsql.=" and mobile_no2 like '%" . $_POST['mobile_no2'] . "%'";
You should use the LEFT() and RIGHT() functions.
I am not 100% sure what you're trying to match but this one will match first digit of mobile_no1 and last digit of mobile_no2 in the mobile_no field.
Try this:
$searcy_query = "SELECT mobile_no, fname, cus_name FROM $table_name
WHERE mobile_no LIKE CONVERT(CHAR(1),LEFT(mobile_no1,1))+'%'
AND mobile_no like '%'+CONVERT(CHAR(1),RIGHT(mobile_no2,1))";
If you are asking to get the results which will have start (input 1) and end (input 2) numbers of the given search
$table_name ='search1_ts1';
if(isset($_POST['tablename']) && !empty($_POST['tablename'])){
$table_name =$_POST['tablename'];
}
$search_query="SELECT mobile_no, fname, cus_name FROM $table_name";
$conditionsql="";
if(isset($_POST['mobile_no1']) && !empty($_POST['mobile_no1'])) {
$conditionsql.=" mobile_no1 like '%" . addslashes($_POST['mobile_no1']) . "'";
}
if(isset($_POST['mobile_no2']) && !empty($_POST['mobile_no2'])){
$conditionsql.=" and mobile_no2 like '" .addslashes( $_POST['mobile_no2'] ). "%'";
}
$search_query = $search_query+'where'+$conditionsql;
i am using this sql search to find a title and artist in my database. I have on field containing infos like "ref.1570 title artist.mp4". When I do the search it works but in one direction only, i would like to get the result whatever the order i do the search... to be more precise if i search "title artist" no problem i found it. If i search "artist title" no way ... how can you help me making php sql search both directions ?
Best regards and thank you for your help.
Phil
i am using this code :
if ($search != null) {
$sql = 'SELECT * FROM `catalog` WHERE (`file`LIKE "%' . $search . '%")';
$sqlCount = 'SELECT count(*) FROM `catalog` WHERE (`file`LIKE "%' . $search . '%")';
}
Why don't you split keyword $search with space and append with Like statement in the query. Eg:
if ($search != null) {
$keywords=explode(" ",$search);
$sql = 'SELECT * FROM `catalog` WHERE 1=1'; // just to append OR condition.This won't affect anything as the condition will always be true.
$sqlCount = 'SELECT count(*) FROM `catalog` WHERE 1=1 ';
foreach($keywords as $key){
if(!empty($key)){
$sql.=' And file Like \'%'.$key.'\%';
$sqlCount.=' And file Like \'%'.$key.'\%';
}
}
}
I believe this will work as you expected.
I think you won't get around a foreach:
if ($search != null) {
$arrayOfSearchTerms = explode(' ', $search);
$sql = 'SELECT * FROM `catalog` WHERE ';
$sqlCount = 'SELECT count(*) FROM `catalog` WHERE ';
$termNumber = 0;
foreach ($arrayOfSearchTerms as $term) {
$addingSql = '';
if ($termNumber > 0) {
$addingSql = ' OR ';
}
$addingSql .= '(`file` LIKE "%') . $term . '%")';
$sql .= $addingSql;
$sqlCount = $addingSql;
$termNumber++;
}
}
You need to iterate over your search terms and add this terms into your 'LIKE'-Statement
you can try this research: it does a LIKE %word% for every word. If you want more powerfull research you should use tools like elasticsearch etc...
This way you could do:
$parts = explode(" ",$search)
$queryParts = array();
foreach ($parts as $part) {
$queryParts[] = `artist`LIKE "%' . $part . '%" ;
}
// this way we can have like %artist% AND like %title%
$querySearch= implode(" AND ", $queryParts);
$sql = 'SELECT * FROM `catalog` WHERE (". $querySearch .")';
$sqlCount = 'SELECT count(*) FROM `catalog` WHERE (`". $querySearch .")';
you have solved my problem i know now hos to correctly explode a request into variables ..
$search = $name;
$explode=explode(" ",$search);
print_r (explode(" ",$explode));
and then i use my sql request like this
$sql = 'SELECT * FROM `catalog` WHERE (`idc` LIKE "%' . $search . '%" OR `file` LIKE "%' . $search . '%" OR `title` LIKE "%' . $explode[0] . '%" AND `artist`LIKE "%' . $explode[1] . '% " OR `artist`LIKE "%' . $explode[0] . '%" AND `title`LIKE "%' . $explode[1] . '%")';
and it is working !
COOL
Use the multi query functions,
in mysqli should be : mysqli_multi_query();
More info on : Mysqli Multiquery
I've written a quick search page for my colleagues using php where it queries the database. Their string is named $wordvariable (they also pick dates etc but that's not important here), here's what I'm doing so far:
$wordvariable = explode(" ", $wordvariable);
$wordvariable = implode("%", $wordvariable);
$Query = mysql_query(
"SELECT * FROM table
WHERE (column1 like '%$wordvariable%' or column2 like '%$wordvariable%')
AND logdatex between $TimeEarlier and $TimeNow"
) or die(mysql_error());
however, this only searches for the words they type in the order they have typed them, e.g. searching "stack overflow" would find "stack this is overflow" but wouldn't find "overflow stack". I hope I've phrased this correctly, any help would be appreciated
Something LIKE this:
$where = "WHERE column1 LIKE '%" . implode("%' OR column1 LIKE '%", explode(" ", $wordvariable)) . "%'";
The short is, just explode the $wordvariable on spaces and then implode those individual words on the phrases that you want.
More verbose including column2:
$words = explode(" ", $wordvariable);
$list1 = implode("%' OR column1 LIKE '%", $words);
$list2 = implode("%' OR column2 LIKE '%", $words);
echo $where = "WHERE (column1 LIKE '%$list1%') OR (column2 LIKE '%$list2%')";
Update your code like here:
$wordvariable = explode(" ", $wordvariable);
$Query = mysql_query(
"SELECT * FROM table
WHERE (column1 like '%" . implode("%' OR column1 Like '%", $wordvariable) . "%'
OR column2 like '%" . implode("%' OR column2 Like '%", $wordvariable) . "%')
AND logdatex between $TimeEarlier and $TimeNow"
) or die(mysql_error());