How do I write where_in statement a subquery using codeigniter active records ?
$query = $this->db->query("SELECT SUM(a.transaction_payment_amount) FROM
transaction_payment a WHERE a.transaction_link IN
(SELECT transaction_link FROM transaction WHERE transaction_type = '22'");
$result = $query->result();
Now how to convert the above query into CI active records ?
I have tried:
$this->db->select("SUM(a.transaction_payment_amount)");
$this->db->from('transaction_payment a');
$this->db->where_in('a.transaction_link', "SELECT transaction_link from transaction WHERE transaction_type = '22'");
$query = $this->db->get();
$result = $query->result();
But it doesn't work.
Try This
$this->db->where_in('a.transaction_link', "SELECT transaction_link from transaction WHERE transaction_type = '22'",false);
if you use false then it will remove single quotes from where_in condition
Sharmas Answer should do the job but if you wish fully supported Query Builder Methods you can try this
$strSubQuery = $this->db
->select("transaction_link")
->from("transaction")
->where("transaction_type",22)
->get_compiled_select();
$query = $this->db
->select("SUM(a.transaction_payment_amount)", false)
->from('transaction_payment a')
->where_in('a.transaction_link', $strSubQuery, false)
->get();
You can change your code as following solution.
Changes your query
$this->db->select("SUM(a.transaction_payment_amount)");
$this->db->from('transaction_payment a');
$this->db->where("a.transaction_link IN (SELECT transaction_link from transaction WHERE transaction_type = '22')", null, false);
//OR you can try other where condition if Sub query return null value than used this below query
$this->db->where("IF(SELECT transaction_link from transaction WHERE transaction_type = '22',a.transaction_link IN (SELECT transaction_link from transaction WHERE transaction_type = '22'), NULL)", null, false);
$query = $this->db->get();
$result = $query->result();
I hope this will helps you. Thanks!
Related
How to do UNION query with PHP CodeIgniter framework's active record query format?
CodeIgniter's ActiveRecord doesn't support UNION, so you would just write your query and use the ActiveRecord's query method.
$this->db->query('SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2');
By doing union using last_query(), it may hamper performance of application. Because for single union it would require to execute 3 queries. i.e for "n" union "n+1" queries. It won't much affect for 1-2 query union. But it will give problem if union of many queries or tables having large data.
This link will help you a lot: active record subqueries
We can combine active record with manual queries.
Example:
// #1 SubQueries no.1 -------------------------------------------
$this->db->select('title, content, date');
$this->db->from('mytable');
$query = $this->db->get();
$subQuery1 = $this->db->_compile_select();
$this->db->_reset_select();
// #2 SubQueries no.2 -------------------------------------------
$this->db->select('title, content, date');
$this->db->from('mytable2');
$query = $this->db->get();
$subQuery2 = $this->db->_compile_select();
$this->db->_reset_select();
// #3 Union with Simple Manual Queries --------------------------
$this->db->query("select * from ($subQuery1 UNION $subQuery2) as unionTable");
// #3 (alternative) Union with another Active Record ------------
$this->db->from("($subQuery1 UNION $subQuery2)");
$this->db->get();
This is a quick and dirty method I once used
// Query #1
$this->db->select('title, content, date');
$this->db->from('mytable1');
$query1 = $this->db->get()->result();
// Query #2
$this->db->select('title, content, date');
$this->db->from('mytable2');
$query2 = $this->db->get()->result();
// Merge both query results
$query = array_merge($query1, $query2);
Not my finest work, but it solved my problem.
note: I didn't need to order the result.
You may use the following method to get the SQL statement in the model:
$this->db->select('DISTINCT(user_id)');
$this->db->from('users_master');
$this->db->where('role_id', '1');
$subquery = $this->db->_compile_select();
$this->db->_reset_select();
This way the SQL statement will be in the $subquery variable, without actually executing it.
You have asked this question a long time ago, so maybe you have already got the answer. if not, this process may do the trick.
by modifying somnath huluks answer, i add these following variable and functions to DB_Active_rec class as follows:
class DB_Active_records extends CI_DB_Driver
{
....
var $unions;
....
public function union_push($table = '')
{
if ($table != '')
{
$this->_track_aliases($table);
$this->from($table);
}
$sql = $this->_compile_select();
array_push($this->unions, $sql);
$this->_reset_select();
}
public function union_flush()
{
$this->unions = array();
}
public function union()
{
$sql = '('.implode(') union (', $this->unions).')';
$result = $this->query($sql);
$this->union_flush();
return $result;
}
public function union_all()
{
$sql = '('.implode(') union all (', $this->unions).')';
$result = $this->query($sql);
$this->union_flush();
return $result;
}
}
therefore you can virtually use unions without dependencies to db_driver.
to use union with this method, you simply make regular active record queries, but calling union_push instead of get.
note: you have to ensure your queries have matching columns like regular unions
example:
$this->db->select('l.tpid, l.lesson, l.lesson_type, l.content, l.file');
$this->db->where(array('l.requirement' => 0));
$this->db->union_push('lessons l');
$this->db->select('l.tpid, l.lesson, l.lesson_type, l.content, l.file');
$this->db->from('lessons l');
$this->db->join('scores s', 'l.requirement = s.lid');
$this->db->union_push();
$query = $this->db->union_all();
return $query->result_array();
would produce:
(SELECT `l`.`tpid`, `l`.`lesson`, `l`.`lesson_type`, `l`.`content`, `l`.`file`
FROM `lessons` l
WHERE `l`.`requirement`=0)
union all
(SELECT `l`.`tpid`, `l`.`lesson`, `l`.`lesson_type`, `l`.`content`, `l`.`file`
FROM `lessons` l
JOIN `scores` s ON `l`.`requirement`=`s`.`lid`)
I found this library, which worked nicely for me to add UNION in an ActiveRecord style:
https://github.com/NTICompass/CodeIgniter-Subqueries
BUT I had to grab the get_compiled_select() method from the dev branch of CodeIgniter first (available here: https://github.com/EllisLab/CodeIgniter/blob/develop/system/database/DB_query_builder.php -- DB_query_builder will be replacing DB_active_rec). Presumably this method will be available in a future production release of CodeIgniter.
Once I added that method to DB_active_rec.php in system/database it worked like a charm. (I didn't want to use the dev version of CodeIgniter as this is a production app.)
try this one
function get_merged_result($ids){
$this->db->select("column");
$this->db->distinct();
$this->db->from("table_name");
$this->db->where_in("id",$model_ids);
$this->db->get();
$query1 = $this->db->last_query();
$this->db->select("column2 as column");
$this->db->distinct();
$this->db->from("table_name");
$this->db->where_in("id",$model_ids);
$this->db->get();
$query2 = $this->db->last_query();
$query = $this->db->query($query1." UNION ".$query2);
return $query->result();
}
This is solution I am using:
$union_queries = array();
$tables = array('table1','table2'); //As much as you need
foreach($tables as $table){
$this->db->select(" {$table}.row1,
{$table}.row2,
{$table}.row3");
$this->db->from($table);
//I have additional join too (removed from this example)
$this->db->where('row4',1);
$union_queries[] = $this->db->get_compiled_select();
}
$union_query = join(' UNION ALL ',$union_queries); // I use UNION ALL
$union_query .= " ORDER BY row1 DESC LIMIT 0,10";
$query = $this->db->query($union_query);
bwisn's answer is better than all and will work but not good in performance because it will execute sub queries first.
get_compiled_select does not run query; it just compiles it for later run so is faster
try this one
$this->db->select('title, content, date');
$this->db->where('condition',value);
$query1= get_compiled_select("table1",FALSE);
$this->db->reset_query();
$this->db->select('title, content, date');
$this->db->where('condition',value);
$query2= get_compiled_select("table2",FALSE);
$this->db->reset_query();
$query = $this->db->query("$query1 UNION $query2");
Here's a solution I created:
$query1 = $this->db->get('Example_Table1');
$join1 = $this->db->last_query();
$query2 = $this->db->get('Example_Table2');
$join2 = $this->db->last_query();
$union_query = $this->db->query($join1.' UNION '.$join2.' ORDER BY column1,column2);
$array = array('classesID' => 6);
$this->db->select()->from($this->_table_name)->where($array)->order_by($this->_order_by);
$query = $this->db->get();
return $query->result();
I need to get the rows where the classesID is 6. Some rows contain 6,5,4.
so i need to use FIND_IN_SET query to retrive where the classesID is 6.
Please guide me
Thanks
I need to get the rows which has student id '4488' and message id '1418'
$id = 1418;
$student_id = 4488;
this->db->select('id, action_status, updated_on, student_ids');
$this->db->where('message_id', $id);
$this->db->where('find_in_set("'.$student_id.'", student_ids) <> 0');
$this->db->from('actions_history');
$query = $this->db->get();
It will return a query like
SELECT id, action_status, updated_on, student_ids FROM actions_history WHERE message_id = '1418' AND find_in_set("4488", student_ids) <>0
Try this
$array = array('classesID' => '5,6,7');
$this->db->select();
$this->db->from($this->_table_name);
$this->db->where("FIND_IN_SET('classesID',".$array['classesID'].")",null,false);
$this->db->order_by($this->_order_by);
$query = $this->db->get();
return $query->result();
You can write the query like this.
return $this->db->where('classesID' , '6')->order_by('column_name','desc')->get('table_name')->result_array();
if Need any help comment
For those who're looking for model (CI v4.x) based solution,
$modal->where("FIND_IN_SET('<string to find>', '<column name>')", null, false)->findAll();
In your case,
$modal->where("FIND_IN_SET('".$array['classesID']."', 'classesID')", null, false)->findAll();
I have this query can someone help me transfer it to codeigniter style in model.
SELECT
a.*,
(
SELECT COUNT(*) FROM `comment` c
WHERE c.comment_article_id = a.`News_News_ID`
) AS counta
FROM
`news_news` a
Update:
I try this and it work nicely but im not sure it is good practice
$sql="SELECT a.*,
( SELECT COUNT(*) FROM comment c WHERE c.comment_article_id = a.`News_News_ID` ) as counta
FROM `news_news` a";
$query = $this->db->query($sql, array('News_Cate_ID' => $cate), $start, $display);
Use join instead of sub query and according to your query you didn't need where condition while using joins
$this->db->select('a.*,COUNT(c.*) AS counta');
$this->db->from('news_news AS a');
$this->db->join('comment AS c', 'c.comment_article_id = a.News_News_ID');
$query = $this->db->get();
For more information
Try below code. This query will return each article with comment count
$this->db->select('a.*,COUNT(c.*) AS count');
$this->db->from('news_news a');
$this->db->join('comment c', 'a.News_News_ID = c.comment_article_id ','LEFT');
$this->db->group_by('a.News_News_ID')
$query = $this->db->get();
Is it possbile to update data with a JOINed tables using Codeigniter's Active Record CI2? I have running code and I want to convert to Codeigniter's Active Record.
public function update_table($job_id, $om_id, $recipient_id)
{
$query = "UPDATE table1 AS t1
INNER JOIN table2 AS t2
ON t1.om_id = t2.id
SET t2.read_date = NOW()
WHERE t2.ref_table_id = $job_id
AND t1.om_id = $om_id
AND t2.recipient_id = $recipient_id
AND t2.read_date = '0000-00-00 00:00:00'";
$result = $this->db->query($query);
return $result;
}
I try like this but doesn't work.
public function update_table($job_id, $om_id, $recipient_id)
{
$this->db->set('t2.read_date', NOW());
$this->db->where('t2.ref_table_id', $job_id);
$this->db->where('t1.om_id', $om_id);
$this->db->where('t2.recipient_id', $recipient_id);
$this->db->where('t2.read_date', '0000-00-00 00:00:00');
$this->db->where('t2.om_id = t1.id');
$this->db->update('table1 AS t1, table AS t2');
}
Any help will be appreciated. Thanks
can you try this..
supply the $condition as array... same with the data that you wanted to update.
function update_data($table, $data, $condition)
{
$this->db->where($condition);
$this->db->update($table, $data);
}
My code is
public function getbonexpense($yr=null)
{
$this->db->select('year(un_due_date) as year,month(un_due_date) as month,sum(coalesce(bank_amount,0) +amount) as bonsum');
$this->db->from('bon_expense');
$this->db->join('bank_expense','bon_expense.id_bon_exp = bank_expense.bon_exp_id', 'left');
$this->db->where('expense_status',3);
$this->db->group_by('year(un_due_date)');
$this->db->group_by('month(un_due_date)');
if(!empty($yr))$this->db->where('year(un_due_date)',$yr);
$this->db->order_by('month(un_due_date)','desc');
$query = $this->db->get();
if($query->num_rows() != 0)
return $query->result_array();
else
return false;
}
but automatically insert codes(`) in running query
SELECT year(un_due_date) as year, month(un_due_date) as month, sum(coalesce(amount, 0)+coalesce(bank_amount, **`0))`** as bonsum
FROM (`crm_bon_expense`)
LEFT JOIN `crm_bank_expense` ON `crm_bon_expense`.`id_bon_exp` = `crm_bank_expense`.`bon_exp_id`
WHERE `expense_status` = 3
AND year(un_due_date) = '2014'
GROUP BY year(un_due_date), month(un_due_date)
ORDER BY month(un_due_date) desc
The single backticks comes in the sum () fuction.How can i avoid it?
add 2nd param FALSE in db -> select method, see below sample code
$this->db->select('year(un_due_date) as year,
month(un_due_date) as month,
sum(coalesce(bank_amount,0) +amount) as bonsum', FALSE);
Documentation:
https://ellislab.com/codeigniter/user-guide/database/active_record.html#select