I'm working on a search module, like facebook when you look for a friend.
So, i have in my table user two fields : firstname and name.
If i have for example a user : firstname : Georges and name : Clooney, i want, when i write :
Geo...
Cloo...
loo geor...
geor ney
etc....
retrieve this user.
How can i do that with SQL ? I want to write a very permissive search module..
This will surely help you
Well the below method first calculate all possible combination of the possible words & then matches it with database
<?php
$name ='Georges Clooney'; // you search string
$words=explode(" ", $name);;
function get_all_combination($arr, $temp_string, &$collect) {
if ($temp_string != "")
$collect []= $temp_string;
for ($i=0; $i<sizeof($arr);$i++) {
$arrcopy = $arr;
$elem = array_splice($arrcopy, $i, 1); // removes and returns the i'th element
if (sizeof($arrcopy) > 0) {
get_all_combination($arrcopy, $temp_string ." " . $elem[0], $collect);
} else {
$collect []= $temp_string. " " . $elem[0];
}
}
}
$collect = array();
get_all_combination($words, "", $collect);
/*
$collect now have all possible combination of search string
Array
(
[0] => Georges
[1] => Georges Clooney
[2] => Clooney
[3] => Clooney Georges
)
*/
$sql="SELECT * FROM user_info WHERE (firstname like '%".implode("%' OR firstname like '%",$collect)."%' or name like '%".implode("%' OR name like '%",$collect)."%')" ;
?>
For any more help do ask
What you need, is this little Friend: %
WHERE firstname LIKE '%" . $name . "%' OR name LIKE '%" . $name ."%'
Here is a tutorial:
http://www.webreference.com/programming/php/search/index.html
Try This:
Select * from User where `name` LIKE '%search_string%' OR `firstname`
LIKE '%search_string%' OR CONCAT(firstname,' ',name) LIKE '%search_string'%'
SELECT *
FROM User
WHERE firstname LIKE '%'+#input+'%' OR name LIKE '%'+#input+'%'
where #input is the inserted text in the textbox.
Try this query:
SELECT * from user
WHERE name LIKE '%search_string%'
OR firstname LIKE '%search_string%'
It will match if any firstname or name containing search_string. it will show all users containing this string in name or first name.
Try this
select * from user where `name` like '%trim(search_string)%' OR `firstname`
like '%trim(search_string)%' OR CONCAT(firstname,' ',name) LIKE '%".trim(search_string)."%';
Also concat both the fields and try to match.
Related
I am creating an advanced search feature for a website and it's almost done, I'm only having one major issue.
I am matching the rooms like this:
AND Rooms=" .$_SESSION["room"] ."
and tried this as well:
AND (Rooms=" .$_SESSION["room"] ." OR Rooms IS NULL)
But the problem is if the user doesn't insert any value in the room input it won't show any room. And with the IS NULL code if I insert "8" in the rooms input if there is no matches it will display all values from the DB.
I don't want to make the input as required.
I just need a solution with mysql for when the field is empty return all values without using this:
if ($_SESSION["room"]==NULL) {}
else{}
Full query:
`SELECT * FROM secret WHERE secretIDName='1' AND NatureTypeIDName LIKE '%" .$_SESSION["nature"] ."%' AND (NettArea>="
.$_SESSION["NettArea"] ." OR NettArea IS NULL) AND ConditionTypeIDName LIKE'%" .$_SESSION["lifestyle"]
."%' AND ((SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',4),'|',-1)>="
.$_SESSION["BusinessTypeValuesMin"]
." AND SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',4),'|',-1)<="
.$_SESSION["BusinessTypeValuesMax"]
.") OR SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',4),'|',-1) = '') AND (SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',2),'|',-1)='"
.$_SESSION["BusinessTypeValuesType"]
."' OR SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',2),'|',-1)='') AND GarageArea>="
.$_SESSION["GarageArea"]
." AND (LocationIDName LIKE '%"
.$_SESSION["zone1"]
."%' AND LocationIDName LIKE '%"
.$_SESSION["zone2"]
."%' AND LocationIDName LIKE '%"
.$_SESSION["zone3"]
."%') AND (Rooms="
.$_SESSION["room"]
.") LIMIT "
.($page-1)*$Page
.", " .$Page ."";`
You can create the condition like this (I assume, that the "rooms" is number representing number of rooms?):
AND (Rooms = ".(int)$_SESSION['room']." OR ".(int)$_SESSION['room']." = 0)
If $_SESSION['room'] is empty (user haven't specified number of rooms), You get
AND (Rooms = 0 OR 0 = 0)
... which is always TRUE, so the "rooms" condition doesn't apply at all. If user specified number of rooms, the query would look like:
AND (Rooms = 8 OR 8 = 0)
The 8 = 0 is always FALSE, so effectively, You have the condition You need: Rooms = 8.
In your query, checking NULL isn't the same as checking empty. I'd recommend the following:
AND (Rooms=" .$_SESSION["room"] ." OR Rooms IS NULL OR Rooms <>'')
Also, it's highly recommended filtering the $_SESSION variable before injecting that into MySQL, if it's a number, assign it to $room=(int)$_SESSION['room'] to force it to be an integer.
There are several solutions, one of them is simply to store the SQL in a string variable, and then add the rooms conditions if the value is not null.
$sql = SELECT ...
if ($_SESSION["room"] !== NULL) {
$sql = $sql . ' AND Rooms=".$_SESSION["room"] . " '
}
Try the query like this: Note i concatenate all php varibles with {} instead of ". ."
SELECT * FROM secret WHERE secretIDName='1' AND NatureTypeIDName LIKE '%{$_SESSION["nature"]}%' AND (NettArea >={$_SESSION["NettArea"]} OR NettArea IS NULL) AND ConditionTypeIDName LIKE'%{$_SESSION["lifestyle"]}%' AND ((SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',4),'|',-1)>={$_SESSION["BusinessTypeValuesMin"]} AND SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',4),'|',-1)<={$_SESSION["BusinessTypeValuesMax"]}) OR SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',4),'|',-1) = '') AND (SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',2),'|',-1)='{$_SESSION["BusinessTypeValuesType"]}' OR SUBSTRING_INDEX(SUBSTRING_INDEX(BusinessTypeValues,'|',2),'|',-1)='') AND GarageArea>={$_SESSION["GarageArea"]} AND (LocationIDName LIKE '%{$_SESSION["zone1"]}%' AND LocationIDName LIKE '%{$_SESSION["zone2"]}%' AND LocationIDName LIKE '%{$_SESSION["zone3"]}%') AND (Rooms={$_SESSION["room"]}) LIMIT ($page-1)*$Page, $Page";
I've researched this but couldn't find a solution for my specific problem.
I have a column containing data in a certain format. Here are some examples:
1
6
14
1;6;14;16
etc...
I need a mysql statement which for example it will select all columns where 16 occurs.
I've tried this but it's also selecting columns where 1 and 6 occur:
"SELECT * FROM tbl WHERE kategorien LIKE '%".$_GET['katid']."%' AND status = 1 ORDER BY pos ASC"
Thanks in advance for any help!
You can try creating a helper function like this:
// Helper function
function getLike($str, $deliminator = ';', $field = 'kategorien') {
if (false !== strpos($str, $deliminator)) {
$strParts = explode($deliminator, $str);
return "($field LIKE '%". implode("%' OR $field LIKE '%", $strParts) . "%')";
} else {
return "$field LIKE '%$str%'";
}
}
// Debug
var_dump(getLike('1;6;14;16'));
Outputs:
string '(kategorien LIKE '%1%' OR kategorien LIKE '%6%' OR kategorien LIKE '%14%' OR kategorien LIKE '%16%')' (length=100)
In your query, you'd use it like this:
"SELECT * FROM tbl WHERE ". getLike($_GET['katid']) ." AND status = 1 ORDER BY pos ASC"
You could use MySQL function FIND_IN_SET:
SELECT * FROM tbl
WHERE
FIND_IN_SET('16', REPLACE(kategorien, ';', ','))>0
however, it is usually not a good idea to store comma separated values in a single field, please have a look at this question: Is storing a delimited list in a database column really that bad?
I'm trying to create a search engine to search for users based on their name.
Here is an example of what I can do at this moment:
I want to search for david (surname) Jones (name)
-> When I type: 'Da' or 'vid' or 'J' or 'ones' it gives me David Jones
BUT when I type 'David J' it gives nothing.
In which way do I have to change my query to search on both fields on the same time?
The query:
public function Search($searchinput)
{
$db = new Db();
$select = "SELECT * FROM tblusers WHERE name LIKE '%" . $searchinput . "%' OR surname LIKE'%" . $searchinput . "%'";
$result = $db->conn->query($select);
return $result;
}
probably for production you can use http://sphinxsearch.com/ because it is MUCH faster than MySQL in searching texts in natural language
Try this query using CONCAT:
$select = "SELECT * FROM tblusers WHERE name LIKE '%". $searchinput ."%' OR surname LIKE '%". $searchinput ."%' OR CONCAT(name,' ',surname) LIKE '%". $searchinput ."%' ";
The problem is that you are trying to match David J in name or surname but as I see your db look as like follows:
Name | Surnam
Davud | Jones
And your like statement is looking for: "David J" into name or surname which give you the right result(zero) because there does not exist any row with name or surname like "David J", in your case the best solution will be to concat the name with surname and then to make like statment upon them:
Select * FROM tbulsers WHERE CONCAT(name, ' ', surname) LIKE "%David J%"
I am trying to select stories for my mysql database Where the author variable is equal to a list of names.
I basically have a list of names that I want use in determining what stories to pull.
$names = "name1 name2 name3 name4"
$get_stories = mysql_query("SELECT * FROM glnce_stories WHERE author = '$names' ORDER BY id DESC");
I know that this isn't the right way to do but I was looking for some solutions on how I might be able to break that list up so I can have it pull from the authors in that $names variable.
Thanks!
If you aren't able to change the format of the $names variable, this should work:
$names = 'name1 name2 name3 name4';
$names = '"' . implode('","', explode(' ', $names)) . '"';
$get_stories = mysql_query('SELECT * FROM glnce_stories WHERE author IN(' . $names . ') ORDER BY id DESC');
comma separate the names and then
use "WHERE author in (" . $names . ")";
You should use WHERE field in (list) like this:
$names = "'name1', 'name2', 'name3', 'name4'";
$get_stories = mysql_query("SELECT * FROM glnce_stories WHERE author in ($names) ORDER BY id DESC");
So, your query should look something like this: SELECT * FROM glnce_stories WHERE author in ('Bob', 'Steve', 'Andrey', 'Mike', 'Jenna')
Rewrite your code as follows:
$names = "name1 name2 name3 name4";
$names = "'".implode ("','", array_map('mysql_real_escape_string', explode(' ', $names))."'";
$get_stories = mysql_query("SELECT * FROM glnce_stories WHERE author in ($names)");
You can use FIND_IN_SET() for that if you want to be lazy. You will just have to turn your names list into a comma-separated string:
$names = "name1,name2,name3,name4";
mysql_query("SELECT * FROM stories WHERE FIND_IN_SET(author, '$names')"
That's maybe easier than a list of OR conditions or preparing a proper string list for an IN clause. (You can _real_escape_string the whole comma separated list, instead of each name.)
I need to implement the following functionality:
I have a name field which contains both name and surname. This is stored in a database and is in the order 'surname name'.
I am implementing a script which searches through these records. Currently, I managed to check if a string contains a space, if it contains a space it means it is a name and not an ID Card Number for instance. Here is the code:
$query = "John Doe";
$checkIfSpaceExists = strpos($query, " ");
if ($checkIfSpaceExists == "")
{
//No Space therefore it is not a name
}
else
{
//Contains space
$queryExploded = explode(" ", $query);
foreach ($queryExploded as $q)
{
//Here I need the functionality so that if someone entered John Doe
//2 different strings are saved, which are
//$string1 = John Doe
//$string2 = Doe Johns
//If the name consists of 3 parts, strings for every combination is saved
}
Then I will insert these strings in an SQL statement with the LIKE attribute and there will be a LIKE for both JOHN DOE and DOE JOHN. Hence, if the user can either enter John Doe or Doe John in order to find the result.
Any suggestions on how to do this?
Many thanks
chris
Ok, from the start - be sure to read the manual carefully. strpos doesn't do exactly what you think it's doing. Here's how you should check for a space:
if (strpos($query, ' ') === false) // the triple-equals is important!
After that, it's simply a matter of permutations and combinations. Here's another answer on Stack Overflow which shows you how to do it: algorithm that will take number or words and find all possible combinations
What about using these exploded 3 strings in separate AND-combined LIKE-constraints?
Something like
"... WHERE name LIKE '%$name[0]%' AND name LIKE '%$name[1]%' AND name LIKE '%$name[2]%'"
You could build this String in a foreach loop.
echo preg_replace('/^(\w+) (\w+)$/', '$2 $1', "John Doe");
Doe John
I guess you cannot split this field into name and surname? I suggest creating new table, tags in database. Tags will be any word - might be surname, may be name, may be ID number... Then make a connection record_tags with record_id and tag_id. Then the query will look like
SELECT record.* FROM record
INNER JOIN record_tags rt1 ON rt1.record_id = record.id
INNER JOIN tag t1 ON t1.id = rt1.tag_id
INNER JOIN record_tags rt2 ON rt2.record_id = record.id
INNER JOIN tag t2 ON t2.id = rt2.tag_id
WHERE
t1.name = "John"
AND t2.name = "Doe"
This will be better approach to searching, as you can then use any amount of words/tags. I think the SQL can be even easier. the multiple-like approach is I think much slower, especially as your database grows.
With some looping and string manipulation, I managed to implement this script.
Here is what I did:
I checked if the query contains a space using strpos. If it contains a space, then it means its a name with both name and surname so I enter a loop in order to output one string with 'name surname' and the other string with 'surname name'
Here is the code:
$like = ""; //This is the LIKE sql command.
foreach ($selectedFields as $field)
{
$checkIfSpaceExists = strpos($query," ");
if ($checkIfSpaceExists != "")
{
$query1 = $query; //No space, so query1 is equal ta original query
$queryExploded = explode(" ", $query);
for ($i=0; $i<count($queryExploded); $i++) //First loop (name surname)
{
$tmp1 = $tmp1 . " " . $queryExploded[$i];
}
for ($i=count($queryExploded); $i>=0; $i--) //Second loop (surname name)
{
$tmp2 = $tmp2 . " " . $queryExploded[$i];
}
$query2 = $tmp2;
$query2 = trim($query2);
$like = $like . $field . " LIKE '%" . $query1 . "%' or " . $field . " LIKE '%" . $query2 . "%' or ";
I hope this helps someone else in need :)