inner join with union in codeigniter - php

i m applying union on single table and i want apply inner join with union in codeigniter on it. how can i do that i have tryed many ways but everytime i got syntax error
this is my code:-
$this->db->select(' COUNT(marks.old_id) AS count, MIN(marks.mark) AS min , MAX(marks.mark) AS max ')
->from('marks')
->where('type', 'hard')
->group_by('marks.id');
$this->db->get();
$query1 = $this->db->last_query();
$this->db->select(' COUNT(marks.old_id) AS count, MIN(marks.mark) AS min , MAX(marks.mark) AS max ')
->from('marks')
->where('type', 'easy')
->group_by('marks.id');
$this->db->get();
$query2 = $this->db->last_query();
$query = $this->db->query($query1 . ' UNION ' . $query2);
// $this->db->select('newuser.*')
// ->from('newuser')
// ->join('marks', 'newuser.id = marks.old_id', 'left')
// ->group_by('newuser.id')
// ->order_by('newuser.id', 'ace');
return $query->result();
please help me...

CodeIgniter's active records don't support UNION, so you would just write your query and use the active records query method. , Please check this post Union query with codeigniter

Codeigniter active record not supporting a union Write a raw query for union...

Related

How to union 2 querys in codeigniter

I have 2 querys.I want to union both querys.When am trying to add both querys not getting result.
Please find below 2 querys. Even i tried to add one single core PHP Query to in codeigniter model
But not getting result. can any one please help me on this query.
Core PHP Based query in model codeigniter-method1
$sql = "select
'Amadeus' AS SupplierName,TST_Type,TKT_Type,TKTNumber,TKT_FO_REF,BasePrice,TaxPrice,Commission1,BasePrice+TaxPrice AS TotalPrice,'issued' AS tkt_type,booking_price.CreatedBy as createdby,`TicketedDate` AS created_date,CONCAT(`a3m`.`firstname`,`a3m`.`lastname`) AS created_name,a3m.account_id,`a3m`.locationvalue AS Location_ID,`a3m`.locationdescription AS Location_Name,`a3m`.costcentervalue AS CostCenter_ID,`a3m`.costcenterdescription AS CostCenter_Name
from
data_flight.booking_price
left join `a3m_account_details` `a3m` ON `a3m`.`account_id` = data_flight.booking_price.CreatedBy
where TKTNumber!=''
union all
select
'Amadeus' AS SupplierName,'' AS TST_Type,'' AS TKT_Type,br_tkt AS TKTNumber,'' AS TKT_FO_REF,br_fare_paid_B AS BasePrice, br_tax_refund_TXT AS TaxPrice,
br_cancellation_penalty AS Commission1, br_fare_total_RFT AS TotalPrice,br_cancel_type AS tkt_type,booking_refund.br_added_by AS createdby,br_refund_date AS created_date ,CONCAT(`a3m`.`firstname`,`a3m`.`lastname`) AS created_name,a3m.account_id,`a3m`.locationvalue AS Location_ID,`a3m`.locationdescription AS Location_Name,`a3m`.costcentervalue AS CostCenter_ID,`a3m`.costcenterdescription AS CostCenter_Name
from
data_flight.booking_refund
left join `a3m_account_details` `a3m` ON `a3m`.`account_id` = data_flight.booking_refund.br_added_by
where br_tkt!=''
";
echo $this->db->query($sql);
COdeigniter based query method2
$this->db->select('"Amadeus" AS SupplierName,TST_Type,TKT_Type,TKTNumber,TKT_FO_REF,BasePrice,TaxPrice,Commission1,(BasePrice+TaxPrice) AS TotalPrice,"issued" AS tkt_type,createdby,TicketedDate as created_date,CONCAT(a3m.firstname," ",a3m.lastname) AS created_name,a3m.account_id,a3m.locationvalue AS Location_ID,a3m.locationdescription AS Location_Name,a3m.costcentervalue AS CostCenter_ID,a3m.costcenterdescription AS CostCenter_Name');
$this->db->from($this->traveldb->database.".booking_price bp");
$this->db->join('a3m_account_details a3m','a3m.account_id=createdby','left');
$this->db->where('TKTNumber !=', '');
$query1 = $this->db->get();
$this->db->select('"Amadeus" AS SupplierName,"" AS TST_Type,"" AS TKT_Type,br_tkt AS TKTNumber,"" as TKT_FO_REF,br_fare_paid_B as BasePrice,br_tax_refund_TXT as TaxPrice,br_cancellation_penalty as Commission1,br_fare_total_RFT AS TotalPrice,br_cancel_type AS tkt_type,br_added_by as createdby,br_refund_date as created_date,CONCAT(a3m.firstname," ",a3m.lastname) AS created_name,a3m.account_id,a3m.locationvalue AS Location_ID,a3m.locationdescription AS Location_Name,a3m.costcentervalue AS CostCenter_ID,a3m.costcenterdescription AS CostCenter_Name');
$this->db->from($this->traveldb->database.".booking_refund bp");
$this->db->join('a3m_account_details a3m','a3m.account_id=br_added_by','left');
$this->db->where('br_tkt !=', '');
$query2 = $this->db->get();
$query = $this->db->query($query1." UNION ".$query2);
echo $this->db->last_query();
I tried both methods in my model not getting result , tried to print query it showing erros. Please help me on this.

How can I achieve a UNION query using Codeigniter's active records? [duplicate]

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);

Codeigniter Subquery

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();

getting three records in descending order of each category using codeigniter

I've two categories and I want to fetch three records of each category later I found this link UNION query with codeigniter's active record pattern after this I change my DB_Active_rec file and add this code also
var $unions = array();
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;
}
and then I create codeigniter's function based query like this
$this->db->select("*");
$this->db->from("media m");
$this->db->join("category c", "m.category_id=c.id", "INNER");
$this->db->order_by("m.media_files", "DESC");
$this->db->limit(3);
$this->db->union_push();
$this->db->select("*");
$this->db->from("media m");
$this->db->join("category c", "m.category_id=c.id", "INNER");
$this->db->order_by("m.media_files", "DESC");
$this->db->limit(3);
$this->db->union_push();
$getMedia = $this->db->union_all();
create this
(SELECT * FROM media m INNER JOIN category c ON
m.category_id = c.id ORDER BY m.media_files DESC LIMIT 3)
UNION ALL
(SELECT * FROM media m INNER JOIN category c ON
m.category_id = c.id ORDER BY m.media_files DESC LIMIT 3)
Now it is fetching records but not properly I want to use only query, it showing six records first query fetch 3 records and second query fetch three records now records are duplicate I check the id of records it is 6,5,4 and again 6,5,4. It can be done also by PHP but I want to use query. Thanks in advance
I dont know code-igniter, but basicly you want it to do the union first and then apply the order by over the whole set. This would require a subquery. It should result in the following SQL query:
select * from
((SELECT * FROM media m INNER JOIN category c ON m.category_id = c.id )
UNION ALL
(SELECT * FROM media m INNER JOIN category c ON m.category_id = c.id)) T
ORDER BY m.media_files DESC LIMIT 3
Hope it helps you some.

Convert this MySQL Query to Codeigniter Active Record

I have got two tables :
Dress (dress_id, title)
Dress_comment (comment_id, dress_id, comment)
I have been trying from hours now and unable to convert this query into the corresponding Codeigniters' Active Class Record functions.
Here is the query :
SELECT d.dress_id, d.title, COALESCE(dc.count, 0)
FROM dress d
JOIN (select dress_id, count(comment_id) as count from dress_comment group by dress_id) dc
ON d.dress_id = dc.dress_id
ORDER BY d.dress_id;
This is what I have tried till now :
//Creating the select subquery for the inner join
$this->db->select('dress_id, count(comment_id) as count')
->from('Dress_comment')
->group_by('dress_id')
->get();
$subQuery = $this->db->last_query();
//Main Query
$this->db->select('d.dress_id, d.title, COALESCE(dc.count,0)')
->from('Dress')
->join($subQuery . ' dc','dc.dress_id = d.dress_id','left')
->order_by('d.dress_id');
$result = $this->db->get();
return $result->result_array();
But Codeigniter is not running this query and always giving mysql syntax error. The sql format that codeigniter is converting this active methods to is
SELECT `d`.`dress_id`, `d`.`title`, COALESCE(dc.count, `0)`
FROM (`Dress`) LEFT JOIN `SELECT` `dress_id`, count(comment_id) as count
FROM (`Dress_comment`)
GROUP BY `dress_id` dc
ON `dc`.`dress_id` = `d`.`dress_id`
ORDER BY `d`.`dress_id`
I was able to solve the problem using the mysql query in the join function like this :
$this->db->select('d.dress_id, d.title, dc.count as comments, dl.count as likes, dt.title, di.image_url')
->from('Dress d')
->join('(select dress_id, count(comment_id) as count from dress_comment group by dress_id) dc','dc.dress_id = d.dress_id','left')
->order_by('d.dress_id');

Categories