Here is my table like below.
Id Firstname Lastname
1 Akhil Mokariya
2 Harshit joshi
When i search the result "Akhil Mokariya" it's give me null record but i need result like below.
1 Akhil Mokariya
My Query is like below.
$searcharray = array(
'students.firstname' => $searchterm,
'students.lastname' => $searchterm,
'students.guardian_name' => $searchterm,
'students.adhar_no' => $searchterm,
'students.samagra_id' => $searchterm,
'students.roll_no' => $searchterm,
'students.admission_no' => $searchterm,
);
$this->db->select('classes.id AS `class_id`,students.id,classes.class,sections.id AS `section_id`,sections.section,students.id,students.admission_no , students.roll_no,students.admission_date,students.firstname, students.lastname,students.image, students.mobileno, students.email ,students.state , students.city , students.pincode , students.religion, students.dob ,students.current_address, students.permanent_address,IFNULL(students.category_id, 0) as `category_id`,IFNULL(categories.category, "") as `category`, students.adhar_no,students.samagra_id,students.bank_account_no,students.bank_name, students.ifsc_code ,students.father_name , students.guardian_name , students.guardian_relation,students.guardian_phone,students.guardian_address,students.is_active ,students.created_at ,students.updated_at,students.gender,students.rte,student_session.session_id')->from('students');
$this->db->join('student_session', 'student_session.student_id = students.id');
$this->db->join('classes', 'student_session.class_id = classes.id');
$this->db->join('sections', 'sections.id = student_session.section_id');
$this->db->join('categories', 'students.category_id = categories.id', 'left');
$this->db->where('student_session.session_id', $this->current_session);
$this->db->group_start();
$this->db->or_like($searcharray);
$this->db->group_end();
$this->db->order_by('students.id');
// $this->db->limit('100');
$query = $this->db->get();
I find in my own searches that I will check to see if the search is for a string that has a space, so I can split it and use it for first and last name:
if( strpos( $searchterm, ' ' ) !== FALSE )
$search_parts = explode(' ', $searchterm);
Then, you may want to make sure that there are two parts:
if( count( $search_parts ) == 2 ){
// you know you have two parts
}
So then you'd be able to use the parts in your array:
'students.firstname' => $search_parts[0],
'students.lastname' => $search_parts[1],
And if they may be out of order:
'students.firstname' => $search_parts[1],
'students.lastname' => $search_parts[0],
I am using a different way of creating a query, but to show you an example, I do this:
if( strpos( $search, ' ' ) !== FALSE )
{
$search_parts = explode(' ', $search);
$sql .= '
OR (
first_name LIKE "%' . $this->db->escape_like_str( current($search_parts) ) . '%" ESCAPE "!" AND
last_name LIKE "%' . $this->db->escape_like_str( end($search_parts) ). '%" ESCAPE "!"
) ';
reset($search_parts);
$sql .= '
OR (
last_name LIKE "%' . $this->db->escape_like_str( current($search_parts) ) . '%" ESCAPE "!" AND
first_name LIKE "%' . $this->db->escape_like_str( end($search_parts) ). '%" ESCAPE "!"
)
';
}
Also, if you don't care about code portability, you should see this answer with CONCAT: Mysql Concat two columns while searching with LIKE
That ends up looking something like this:
// Check if search was input as full name
if( strpos( $search, ' ' ) !== FALSE )
{
$sql .= '
OR ( CONCAT( first_name, " ", last_name ) LIKE "%' . $this->db->escape_like_str( $search ) . '%" ESCAPE "!" )
OR ( CONCAT( last_name, " ", first_name ) LIKE "%' . $this->db->escape_like_str( $search ) . '%" ESCAPE "!" ) ';
}
So, in your case, I think you should be able to do this:
$searcharray = array(
'students.firstname' => $searchterm,
'students.lastname' => $searchterm,
'students.guardian_name' => $searchterm,
'students.adhar_no' => $searchterm,
'students.samagra_id' => $searchterm,
'students.roll_no' => $searchterm,
'students.admission_no' => $searchterm,
'CONCAT(students.firstname, " ", students.lastname)' => $searchterm,
'CONCAT(students.lastname, " ", students.firstname)' => $searchterm
);
Related
At first , I apologize for my poor English.
environmental information
language: PHP 7.4.13
framework: CakePHP 4.2.6
At the SQL DB table, there are 6 colmuns.
(columnA , columnB , columnC , columnD , columnE , columnF)
I want to search from the concatnated columns.
I want to "OR search" with 4 conditions.
Whether '${columnA}.${columnC}' matches $str
or
Whether '${columnB}.${columnC}' matches $str
or
Whether '${columnD}.${columnF}' matches $str
or
Whether '${columnE}.${columnF}' matches $str
Now , I write as this to search with one condition .
$query->where(function ($exp, $q) use($str) {
$concat = $q->func()->concat([
'columnA' => 'identifier',
'columnC' => 'identifier'
]);
return $exp->like($concat, '%' . $str . '%' );
});
If I search from "not concatnated columns" , I write this .
$query->where([
0 => [
'or' => [
'${columnA} LIKE' => '%' . $str . '%' ,
'${columnB} LIKE' => '%' . $str . '%' ,
'${columnC} LIKE' => '%' . $str . '%' ,
'${columnD} LIKE' => '%' . $str . '%' ,
]
],
]);
Finally , I want to do something like this.(Ofcourse , this throws a syntax error )
$query->where([
0 => [
'or' => [
'${columnA}.${columnC} LIKE' => '%' . $str . '%' ,
'${columnB}.${columnC} LIKE' => '%' . $str . '%' ,
'${columnD}.${columnF} LIKE' => '%' . $str . '%' ,
'${columnE}.${columnF} LIKE' => '%' . $str . '%' ,
]
],
]);
Can someone help me?
The query expression object has an or() method that you can use, it either takes an array of conditions that are combined using OR, or a callable that receives a new query expression object that uses the OR operator.
In any case you need to be aware that QueryExpression::like() will not return a new expression object, but it will add a new like expression to the current query expression object's stack instead.
That being said, the callback variant would look something like this:
$query->where(function (
\Cake\Database\Expression\QueryExpression $exp,
\Cake\ORM\Query $q
) use (
$str
) {
return $exp->or(function ($exp) use ($q, $str) {
$concatAC = $q->func()->concat([
'columnA' => 'identifier',
'columnC' => 'identifier'
]);
$concatBC = $q->func()->concat([
'columnB' => 'identifier',
'columnC' => 'identifier'
]);
return $exp
->like($concatAC, '%' . $str . '%')
->like($concatBC, '%' . $str . '%')
// ...
});
});
The former variant can be used by passing an empty array, that way you receive an empty query expression object that you can then fill with your conditions:
$query->where(function (
\Cake\Database\Expression\QueryExpression $exp,
\Cake\ORM\Query $q
) use (
$str
) {
// ...
return $exp
->or([])
->like($concatAC, '%' . $str . '%')
->like($concatBC, '%' . $str . '%')
// ...
});
Lastly you can also at any point change the string used for concatenating the expressions by any query expression object using QueryExpression::setConjunction():
$query->where(function (
\Cake\Database\Expression\QueryExpression $exp,
\Cake\ORM\Query $q
) use (
$str
) {
// ...
return $exp
->setConjunction('OR')
->like($concatAC, '%' . $str . '%')
->like($concatBC, '%' . $str . '%')
// ...
});
All three variants will result in the same SQL, that is:
WHERE (
CONCAT(columnA, columnC) LIKE %...% OR
CONCAT(columnB, columnC) LIKE %...% OR
...
)
See also
Cookbook > Database Access & ORM > Query Builder > Advanced Conditions
How can I write the follow sql query in MeDoo???
SELECT * FROM lockers WHERE Active = 1 AND GymID = " . $gimid . " AND ForMale = " . $male .
($filter ? " AND Locker LIKE '%" . $filter . "%'" : "")
The problem for me is the conditional LIKE.
$total = $this->db->count('lockers',
['AND' => [
'Active' => 1,
'GymID' => $gimid,
'ForMale' => $male
]]
);
Some suggestion????
Thanks a lot!!!
Finally, I solved it in the follow way:
// getting locker's total
$total = $this->db->debug()->count('lockers', [
'AND' => [
'Active' => 1,
'GymID' => $gimid,
'ForMale' => $male,
'Locker[~]' => $filter ? $filter : '' //<- LIKE with empty string shows all
]
]);
i don't know what is the problem with my query
i want to add a specific range, then add the id of the range to the table of items within the same form
$range_info = array (
'min_price' => $_POST['min_price'],
'max_price' => $_POST['max_price']
);
$item_info = array (
'item_name' => $_POST['item_name'],
'cat_id' => $cat_id,
'total_quantity' => $_POST['total_quantity'],
'available_for_sale' => $_POST['available_for_sale'],
'description' => $_POST['desc'],
'user_id' => $data['user_id']
);
$range_fields = '`' . implode("`, `", array_keys($range_info)) . '`';
$range_data = '\'' . implode("', '", $range_info) . '\'';
$fields = '`' . implode("`, `", array_keys($item_info)) . '`';
$data = '\'' . implode("', '", $item_info) . '\'';
mysql_query("INSERT INTO range($range_fields) VALUES ($range_data); INSERT
INTO items($fields, `range_id`) VALUES ($data, '".mysql_insert_id()."'");
You need to separate your queries (and you forgot to close a parentheses) here :
mysql_query("INSERT INTO range($range_fields) VALUES ($range_data)");
mysql_query("INSERT INTO items($fields, `range_id`) VALUES ($data, '".mysql_insert_id()."')");
Note that your queries are insecure! try to sanitize the data of your post before using it or use prepared statements with mysqli or move to PDO instead!
Store the insert queries into a separate variable and run
$range_info = array (
'min_price' => $_POST['min_price'],
'max_price' => $_POST['max_price']
);
$item_info = array (
'item_name' => $_POST['item_name'],
'cat_id' => $cat_id,
'total_quantity' => $_POST['total_quantity'],
'available_for_sale' => $_POST['available_for_sale'],
'description' => $_POST['desc'],
'user_id' => $data['user_id']
);
$range_fields = '`' . implode("`, `", array_keys($range_info)) . '`';
$range_data = '\'' . implode("', '", $range_info) . '\'';
$fields = '`' . implode("`, `", array_keys($item_info)) . '`';
$data = '\'' . implode("', '", $item_info) . '\'';
/*insert queries*/
$qr1 = "INSERT INTO range($range_fields) VALUES ($range_data)";
$qr2 = "INSERT INTO items($fields, `range_id`) VALUES ($data, '".mysql_insert_id()."')";
mysql_query($qr1);
mysql_query($qr2);
Note:
The original MySQL extension is now deprecated, and will generate E_DEPRECATED errors when connecting to a database. Instead, use the MySQLi or PDO_MySQL extensions.
MySQLi tutorial: https://www.w3schools.com/PhP/func_mysqli_connect.asp
I have some trouble with $query->bindParam. It doesn't change placeholders into values.
$options is an array:
$options['where'] = [
'id' => [ 1, 2, 3 ],
'title' => [ 'some', 'title' ]
];
$fields = '*';
$where_clauses = []; /* define empty error which could be filled with where clauses */
/* if it is a separte blog, only posts posted by it's admin should be got */
if ( Main::$current_blog_id !== 1 )
$where_clauses[] = '`author_id` IN(' . $this->blog->admin_id . ')';
/* if options have been passed */
if ( ! empty( $options ) ) {
/* if there are "where" options */
if ( ! empty( $options['where'] ) ) {
$placeholder_number = 1; /* define placeholder number */
$placeholders = []; /* create array with placeholders 'placeholder_number' => 'value' */
foreach ( $options['where'] as $field_name => $values ) {
$field_values = []; /* values that will be used to create "IN" statement */
/* fill $fild_values array with values */
foreach ( $values as $value ) {
$placeholder = ':' . $placeholder_number; /* create placeholder */
$field_values[] = $placeholder; /* add placeholder to field values */
$placeholders[ $placeholder ] = $value; /* add placeholer with it's value to common placeholders array */
$placeholder_number++; /* increase placeholder number */
}
/* turn $fields_values array into string */
$field_values = implode( ', ', $field_values );
/* create clause and put it into $where_clauses */
$where_clauses[] = '`' . $field_name . '` IN(' . $field_values . ')';
}
}
}
/* if where statement is empty */
$where_clauses =
! empty( $where_clauses ) ?
implode( ' AND ', $where_clauses ) :
1;
$query = Main::$data_base->pdo->prepare(
'SELECT ' . $fields . ' ' .
'FROM `posts` ' .
'WHERE ' . $where_clauses . ' ' .
'LIMIT ' . $posts_quantity . ';'
);
/* if there are placeholders in the query */
if ( ! empty( $placeholders ) ) {
foreach ( $placeholders as $placeholder => $value )
$query->bindParam( $placeholder, $value, PDO::PARAM_STR );
}
$query->execute();
$posts = $query->fetchAll( PDO::FETCH_ASSOC );
var_dump( $query );
return
! empty( $posts ) ?
$posts :
[];
After all of this my printed query looks like:
SELECT * FROM `posts` WHERE `id` IN(:1, :2, :3) AND `title` IN(:4, :5) LIMIT 15;
You need to define the binds like...
Array ( ':1' => 1, ':2' => 2, ':3' => 3, ':4' => 'some', ':5' => 'title' )
Also your select is incorrect...
"SELECT * FROM posts WHERE id IN(:1, :2, :3) AND title IN(:4, :5) LIMIT 15;"
You have to put AND and not && in there.
PDOStatement::bindParam doesn't modify the query string that you passed to PDO::prepare. It replaces the placeholders with the value of the variable that you bound to it in the moment you execute the statement and the query is sent to the SQL server.
This should be what you want:
$query = "SELECT * FROM posts WHERE id IN (:1, :2, :3) AND title IN (:4, :5) LIMIT 15;";
$statement = $db->prepare($query); // $db contains the connection to the database
$placeholders = array(':1' => 1, ':2' => 2, ':3' => 3, ':4' => 'some', ':5' => 'title');
foreach ($placeholders as $placeholder => $value) {
$statement->bindValue($placeholder, $value, PDO::PARAM_STR);
}
$statement->execute();
Note that I use PDOStatement::bindValue and that I modified your SQL query string (and instead of &&).
You could also do this:
$query = "SELECT * FROM posts WHERE id IN (:1, :2, :3) AND title IN (:4, :5) LIMIT 15;";
$statement = $db->prepare($query);
$placeholders = array(':1' => 1, ':2' => 2, ':3' => 3, ':4' => 'some', ':5' => 'title');
$statement->execute($placeholders);
Read about PDOStatement::execute in the docs.
I have issues with OR conditions in cake php query builder. This will return 0 result.
$results = $this->paginate('Did', array('Did.ivr_id LIKE ' => $number . "%",'OR'=>array('Did.did LIKE ' => $number . "%")));
$result = $this->paginate = array(array('Did.did LIKE' => $number . "%"));
$this->set('dids', $results);
When i apply condition on simple column it gives accurate result
$results = $this->paginate('Did', array('Did.ivr_id LIKE' => $number . "%"));
$result = $this->paginate = array(array('Did.did LIKE' => $number . "%"));
$this->set('dids', $results);
You need to put all the conditions that you want to OR inside the OR array.
$results = $this->paginate(
'Did',
array(
'OR'=>array(
'Did.ivr_id LIKE ' => $number . "%",
'Did.did LIKE ' => $number . "%"
)
)
);