I'm working on a search function, it was working fine four days ago, now it's returning this error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND state = 'AZ '' at line 1
what is the proper syntax for this line?
if($search_state !== "") {
$query .="AND state = '" . $search_state . " ' " ;
the entire portion is:
$query = "SELECT id, name, contact, contact2, address1, address2, city, state, postalcode, country, location, workphone, fax, email, webaddress, region, rail, food, forest, metal, bulk, chem, general, paper FROM companies_new WHERE dummy = '' ORDER BY state ASC ";
if($search_co !== "") {
$query .= "AND name LIKE '%" . $search_co ."%' ";
}
if($search_first !== "") {
$query .= "AND contact LIKE '%" .$search_first."%' ";
}
if($search_last !== "") {
$query .= "AND contact LIKE '%" .$search_last."%' ";
}
if($search_city !== "") {
$query .="AND city = ' " . $search_city . " ' ";
}
if($search_state !== "") {
$query .="AND state = '" . $search_state . " ' " ;
}
You can't put AND conjunctions for your WHERE clause after an ORDER BY. Your ORDER BY clause has to come after the entirety of the WHERE clause.
You need to put the AND statements after the where, and before the sort_by.
Move the sort_by to the end of the php (append to the query string), and it should work.
Try this:
$query = "SELECT id, name, contact, contact2, address1, address2, city, state, postalcode, country, location, workphone, fax, email, webaddress, region, rail, food, forest, metal, bulk, chem, general, paper FROM companies_new WHERE dummy = '' ";
if($search_co !== "") {
$query .= "AND name LIKE '%".$search_co."%' ";
}
if($search_first !== "") {
$query .= "AND contact LIKE '%".$search_first."%' ";
}
if($search_last !== "") {
$query .= "AND contact LIKE '%".$search_last."%' ";
}
if($search_city !== "") {
$query .= "AND city = '".$search_city."' ";
}
if($search_state !== "") {
$query .= "AND state = '". $search_state."' " ;
}
$query.= "ORDER BY state ASC"
As was said by others, your order by statement has to come last. Also, you had spaces surrounding the city name in the city = portion of the query. While this is valid SQL syntax, it's only going to return results where the city name is surrounded by spaces. I'm guessing that's not what you wanted.
Also, you may want to add some more fields to your order by. Right now, it will order by state, but will records come back randomly by state. Maybe something like
$query.= "ORDER BY state, city, name, id"
Finally, just FYI, if you're not carefully sanitizing your search inputs, this approach is susceptible to SQL Injection.
Also, you seem to have spaces between the single and double quotes which will make the query like this: AND state = ' AZ ' which is probably not what you want. You can also avoid the additional quotes and concatenations in PHP by using this syntax:
$query .= " AND state = '$search_state' ";
Of course I have to mention that you should sanitize your inputs to protect against SQL injection.
The WHERE part comes before the AND's in your code, which is wrong. This is what you want
$query = "SELECT id, name, contact, contact2, address1, address2, city, state, postalcode, country, location, workphone, fax, email, webaddress, region, rail, food, forest, metal, bulk, chem, general, paper FROM companies_new WHERE dummy = '' ";
if($search_co !== "") {
$query .= "AND name LIKE '%" . $search_co ."%' ";
}
...
$query .= " ORDER BY state ASC ";
Also, for completeness sake, you could make the code a bit easier to read:
$query .= "AND name LIKE '%$search_co%' ";
because your string is double quoted
I think this might work:
$query = "SELECT id, name, contact, contact2, address1, address2, city, state, postalcode, country, location, workphone, fax, email, webaddress, region, rail, food, forest, metal, bulk, chem, general, paper FROM companies_new ";
$conditions = array();
if(!empty($search_co)) {
$conditions[] = "name LIKE '%" . $search_co ."%' ";
}
if(!empty($search_first)) {
$conditions[] = "contact LIKE '%" .$search_first."%' ";
}
if(!empty($search_last)) {
$conditions[] = "contact LIKE '%" .$search_last."%' ";
}
if(!empty($search_city)) {
$conditions[] = "city = '" . $search_city . "' ";
}
if(!empty($search_state)) {
$conditions[] = "state = '" . $search_state . "' " ;
}
if (count($conditions) > 0) {
$query .= " WHERE " . implode(' AND ', $conditions);
}
$query .= " ORDER BY state ASC";
Edit: The original version used empty, it should have been !empty. It's fixed now.
Edit 2: This also assumes you've already sanitized the variables using mysql_real_escape_string or similar.
Note that ORDER BY has to be after the WHERE clauses.
implode takes an array and turns it into a string with the specified string between the elements. So, given:
$myArray = array('A', 'B', 'C');
you can do
$myString = implode(' and ', $myArray);
which would put "A and B and C" into $myString.
Related
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 have simple query for full text search, data comes from HTML form inputs. If statement checks or it was filled all three inputs with array_key_exists and then concatenate all strings, but if someone didn't fill first or second input and then my query WHERE part is WHERE AND contract = $var so in this situation AND is not needed. What is solution for my problem, how i can solve this? When AND is needed just add to query string and when didn't needed don't add.
$sql = "SELECT
slug,
title,
company,
location,
email,
street,
city,
phone,
url,
description,
image,
created_at
FROM jobs
WHERE ";
array_key_exists('paieska', $segment) ? $sql .= "MATCH(title, description) AGAINST('".urldecode($segment['paieska'])."') " : '';
array_key_exists('darbo-laikas', $segment) ? $sql .= "AND contract = '".$segment['darbo-laikas']."' " : '';
array_key_exists('miestas', $segment) ? $sql .= "AND location = '".$segment['miestas']."'" : '';
The easiest solution is to just add a 1 to the original where statement (And AND before your first $sql if statement). This will always be true, and will return all the records.
If darbo-laikas exists, your query would be ...FROM jobs WHERE 1 AND contract... which would work correctly.
$sql = "SELECT
slug,
title,
company,
location,
email,
street,
city,
phone,
url,
description,
image,
created_at
FROM jobs
WHERE 1 ";
array_key_exists('paieska', $segment) ? $sql .= "AND MATCH(title, description) AGAINST('".urldecode($segment['paieska'])."') " : '';
array_key_exists('darbo-laikas', $segment) ? $sql .= "AND contract = '".$segment['darbo-laikas']."' " : '';
array_key_exists('miestas', $segment) ? $sql .= "AND location = '".$segment['miestas']."'" : '';
try this, add 'AND' in every last statement
array_key_exists('paieska', $segment) ? $sql .= "MATCH(title, description) AGAINST('".urldecode($segment['paieska'])."') AND " : '';
array_key_exists('darbo-laikas', $segment) ? $sql .= "contract = '".$segment['darbo-laikas']."' AND " : '';
array_key_exists('miestas', $segment) ? $sql .= "location = '".$segment['miestas']."' AND " : '';
before execute, delete last char('AND') using
rtrim($sql, "AND ")
note: rtrim should with whitespace, because your 'AND ' using whitespace too
I need to set up a SQL query with multiple parameters that are being pulled from the URL. So far I can only get it to work with the there is only one item in the URL.
My default query to pull in all the content
$sql = "SELECT ";
$sql .= "* ";
$sql .= "FROM ";
$sql .= "cms_site_content ";
$sql .= "WHERE ";
$sql .= "1";
I then check if anything was passed through the URL and retrieve it.
if (isset($_GET["d"])) {
$d=$_GET["d"];
Inside the if statement, I break the values passed as "d" into separate items
$newD = explode(',',$d);
$countD = count($newD);
foreach($newD as $discipline) {
if ($countD == 1) {
$sql .= " AND";
$sql .= " discipline='".$discipline."'";
}
My problem is getting the SQL to work if there is more than one discipline value. It should read something like this:
SELECT * FROM cms_site_content WHERE 1 AND discipline="value"
however if there's more than one discipline value, it should read:
SELECT * FROM cms_site_content WHERE 1 AND discipline="value OR discipline="value2" OR discipline="value3"
Is there a more efficient way to write this? I can't figure out how to insert the OR into the foreach statement.
Save all discipline values in an array;
$discipline_arr = array();
foreach($newD as $discipline) {
$discipline_arr[] = $discipline;
// by the way, don't forget to escape for sql injection
// mysql_escape_string is the depracated one, u can use that if u have no
// other choice
}
Then in your sql, add them as discipline in ('value1','value2', 'etc ...') condition (that is for strings, for numeric types it would be like discipline in (1,2,3,4, etc)
$sql = " SELECT * FROM cms_site_content WHERE 1 " .
(empty($discipline_arr) ? "" : "and
discipline in ('". implode("','" , $discipline_arr). "') ") ;
Link to escaping
http://tr1.php.net/manual/en/function.mysql-escape-string.php
Assuming the rest of your query is in tact. Simply store all of your discipline values in an array as follows, then feed the $discipline_string to your $sql query:
$discipline_ary = array('option1', 'option2', 'option3');
$discipline_string = "";
for($i=0; $i < count($discipline_ary); $i++){
$discipline_string .= " discipline = '" . $discipline[$i] . "' ";
if($i+1 == count($discipline_ary)){
break;
}else{
$discipline_string .= " OR "
}
}
I'm having a little trouble with a search form I've been creating the functionality for. I basically want a form (on whatever page) to go to this page then list the relevant rows from my database. My problem is that the form has both a text field and a select field (for name and categories) and I've been unable to create the functionality for having these two values search the database together.
So heres what I want to happen: When you only type in the name and not the category, it will display from just the name, vise versa for the category and no name; then when both together it only displays rows with both of them in.
Heres what I have so far:
// 2. Create variables to store values
if(!$_GET['search-category'] == "") {
$searchName = $_GET['search-name'];
}
if(!$_GET['search-category'] == "select-your-category") {
$searchCat = $_GET['search-category'];
}
// 2. Create the query for the stored value. Matching it against the name, summary and sub type of my item.
$mainSearch = "SELECT attraction.*, type.type_name, sub_type.sub_type_name ";
$mainSearch .= "FROM attraction ";
$mainSearch .= "INNER JOIN sub_type ON attraction.sub_type = sub_type.sub_type_id ";
$mainSearch .= "INNER JOIN type ON attraction.type = type.type_id ";
$mainSearch .= "WHERE attraction.name LIKE '%" . $searchName . "%' AND (sub_type.sub_type_name LIKE '%" . $searchCat . "%' )";
$mainSearch .= "ORDER BY sub_type_name ASC";
// 2. run query
$result2 = $con->query($mainSearch);
if (!$result2) {
die('Query error: ' . mysqli_error($result2));
}
I'd refactor the code to something like -
foreach( $_GET['filters'] as $fname => $fval ) {
if( !$fval ) continue;
$where[] = "$fname LIKE '%{$fval}%'";
}
You need to include only those inputs that are non-empty in the query. Also you will need to address security issues like escaping inputs etc.
What you can do is that declare a variable called $search_condition and based on whether $searchName or $searchCat is null or not assign value to $search_condition
For e.g.
if (isset($searchName ) || !is_empty($searchName ))
{
$search_condition = "WHERE attraction.name LIKE '%" . $searchName;
}
if (isset($searchCat ) || !is_empty($searchCat ))
{
$search_condition = "sub_type.sub_type_name LIKE '%" . $searchCat . "%'";
}
if ((isset($searchName ) || !is_empty($searchName )) && (isset($searchCat ) || !is_empty($searchCat )))
{
$search_condition = "WHERE attraction.name LIKE '%" . $searchName . "%' AND (sub_type.sub_type_name LIKE '%" . $searchCat . "%' )";
}
Hope this might help you
Thanks
This is a comment, but I want to take advantage of formatting options...
You know, you can rewrite that this way...
// 2. Create the query for the stored value. Matching it against the name, summary and sub type of my item.
$mainSearch = "
SELECT a.*
, t.type_name
, s.sub_type_name
FROM attraction a
JOIN sub_type s
ON a.sub_type = s.sub_type_id
JOIN type t
ON a.type = t.type_id
WHERE a.name LIKE '%$searchName%'
AND s.sub_type_name LIKE '%$searchCat%'
ORDER
BY s.sub_type_name ASC;
";
You can just check that the relevant values aren't empty:
// 2. Create the query for the stored value.
// Matching it against the name, summary and sub type of my item.
$mainSearch = "SELECT attraction.*, type.type_name, sub_type.sub_type_name ";
$mainSearch .= "FROM attraction ";
$mainSearch .= "INNER JOIN sub_type ON attraction.sub_type = sub_type.sub_type_id ";
$mainSearch .= "INNER JOIN type ON attraction.type = type.type_id ";
$mainSearch .= "WHERE ";
if ($searchName) {
$mainSearch .= "attraction.name LIKE '%" . $searchName . "%'";
if ($searchCat) {
$mainSearch .= " AND ";
}
}
if ($searchCat) {
$mainSearch .= "sub_type.sub_type_name LIKE '%" . $searchCat . "%'"
}
$mainSearch .= "ORDER BY sub_type_name ASC";
// Double check that at least one of the search criteria is filled:
if (!$searchName && !$searchCat) {
die("Must supply either name search or category search");
}
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}%'