Codeigniter join, group_by and max - php

I can't find a way to get it working. I have to tables, the first with orders and the second with trackings. I want to add the latest tracking row to left table row.
This is what I've tried so far (doesn't work):
$this->db->select('orders.*, trackings.id AS trackings_id, trackings.order_id AS trackings_order_id, MAX(trackings.status) AS trackings_status, trackings.created_at AS trackings_created_at, trackings.updated_at AS trackings_updated_at, trackings.ip_address AS trackings_ip_address');
$this->db->from('orders');
$this->db->join('trackings', 'orders.id = trackings.order_id', 'left');
$this->db->group_by('trackings.order_id');
$this->db->order_by('orders.created_at', 'DESC');
$query = $this->db->get();
return $query->result();

Woooh, I hate CI's active records, this is a real pain in the butt most of times...
First of all, I'd group by orders.id
Secondly, would be great if you'd define "not working" (gives wrong results? doesn't execute at all?)
P.S. Sorry for posting it as answer (I'd prefer comment) but my rep is still kinda low...

Related

Refining My Eloquent Query (Laravel)

Edited for Clarity:
I need some way for this Query to only return distinct course_ids in the
->wherein('course_id', $array)
part of the query. It gets the total number of completed courses, but if a user has completed a course more than once it counts it toward the total. So if you want to know how many students have done a course, the number will be off if a student has completed a course more than once.
public function report_count(){
$array = \Session::get('course_report')['course'];
return $this->hasOne('Tracking', 'roster_id')
->selectRaw('roster_id, count(*) as aggregate')
->where('status', 1)
->wherein('course_id', $array)
->groupBy('roster_id');
I've tried adding groupBy('course_id') at the end but it does not work.
Fixed. Changed the query to
return $this->hasOne('Tracking', 'roster_id')
->selectRaw('roster_id, count(distinct course_id) as aggregate')
->where('status', 1)
->wherein('course_id', $array)
->groupBy('roster_id');
per #Robin R suggestion, I went on a search of ways to utilize SQL in my selectRaw query instead of trying this the eloquent way. Thanks to all who helped me brainstorm though this one.

Join query codeigniter with where condition returns all rows

Here is my join query for getting data from two tables.
$this->db->select('*');
$this->db->from('george_hotel_bkd_customers');
$this->db->where('george_hotel_bookings.bookingref',$ref);
$this->db->join('george_hotel_bookings', 'george_hotel_bookings.user_id = george_hotel_bkd_customers.user_id');
$query = $this->db->get();
According to my where condition it returns only one row but it will returns all the rows with matches the join condition.
Seems like my where condition is not executed here.
please help me
What does $ref =, how many results should it pick up roughly?
what do you get when you omit the where? if you get full result then must be an issue with $ref value, or, that is the result.
Just a note, you don't need to select(*), this is default, if this is an just for examples sake, sorry for picking up. You can also add the ->from(whaterver_table) to ->get(whatever_table) You need to add ->get() anyway, so why not remove the ->from() line, just a choice of readability, but i did not realise you could do this for a while, so thought id add it to my answer.
Or another problem solving path is whether the join should be 'left' as 3rd arg. IE is there always a join?
Altering the position or the join in the statement would not make any difference, as Anant suggested
$this->db->select('*');
$this->db->from('george_hotel_bkd_customers');
$this->db->join('george_hotel_bookings', 'george_hotel_bookings.user_id = george_hotel_bkd_customers.user_id');
$this->db->where('george_hotel_bookings.bookingref',$ref);
$query = $this->db->get();
always where is last

Codeigniter 2.1 - active record

I have reached dead end with the brain o.O. In DB I have two tables:
store_module->caffe_id, module_id, position, order
module->id_module, name, description, image
I have query where I take all modules for set ID (store_module table), and I need to get all modules which appear in this query (module_id). What I need to do?
This is the code (I am awake for 30+ hours and my brain is refusing to communicate with me, deadline is almost here, and this on of the last things I need to do. So, please help :D):
function mar_get_modules($id){
$q = $this->db->get_where('store_module', array('caffe_id' => $id));
$modules = $q->result_array();
}
Start simple, by using a regular query (if I guess right, you need a JOIN there).
This query should work:
$sql = "SELECT m.*,sm.* FROM module m
LEFT JOIN store_module sm ON sm.id_module = m.module_id
WHERE sm.caffe_id = ?";
return $this->db->query($sql, array($id))->result_array();
Now, you can transform it into an AR query:
$query = $this->db->select('module.*,store_module.*')
->from('module')
->join('store_module', 'store_module.id_module = module.module_id','left')
->where('store_module.caffe_id',$id)
->get();
return $query->result_array();
While AR is quicker sometimes, I usually prefer writing my queries "by hand", taking advantage of the binding to prevent SQL injections; it's a lot easier to see how things are working if you have a query fully laid under your eyes
Sasha,
In the function above, you are not returning anything. You'll need to update the 3rd line something to the effect of return $q->result_array();

codeigniter database query / mysql

I have written a query with codeigniters database library, it looks like this,
public function getCandidateCredits($candidate_id)
{
$this->db->select('*')
->from('credits')
->join('candidate_has_credits', 'candidate_has_credits.credits_credit_id = credits.credit_id', 'left')
->where('credits.candidates_candidate_id', (int)$candidate_id)
->order_by('candidate_has_credits.date_created', 'DESC')
->order_by('credits.credit_position', 'DESC');
$query = $this->db->get();
return $query->result_array();
}
What this query is meant to do is, get all a members credits, and the order them firstly by date (newest first), then by credit position (highest number first).
I am having a couple of problems though, the credits should be ordered by date, but only if there is no credit position, if there is a credit position (0 - 999) then that should take precendence where ordering the credits, if there is a date and a credit position then the credits should be ordered by credit position and then date.
Is this possible? I feel like I am miles away from where I need, the results I return seem to be return no obvious ordering. Not sure if it makes a difference but the date_created field is a DATETIME.
You are correctly using a left join, but have put the order by clauses in the wrong order, so first of all, flip them:
->order_by('credits.credit_position', 'DESC')
->order_by('candidate_has_credits.date_created', 'DESC')
This should do it, except that now those candidate_has_credit rows that do not have corresponding credits records (so the credit_position is null) will be in the end, and I assume you want those on top.
There is a small trick to push null values to top when using DESC sorting providing you know the maximum value available in that field:
->order_by("ifnull('credits.credit_position',1000) desc,candidate_has_credits.date_created desc")
Note that I am using the form of order_by method which contains only one parameter, that one should not escape the function and is marginally faster.
Check the ifnull documentation to see how it works.
Here's a shortened version:
public function getCandidateCredits($candidate_id)
{
return $this->db->from('credits')
->join('candidate_has_credits', 'candidate_has_credits.credits_credit_id = credits.credit_id', 'left')
->where('credits.candidates_candidate_id', (int)$candidate_id)
->order_by('credits.credit_position', 'DESC')
->order_by('candidate_has_credits.date_created', 'DESC')
->get()->result_array();
}

CodeIgniter - ActiveRecord order_by() being applied to all queries not just the one I want

Probably quite a simple one, but I'm not having any luck in the docs or searches.
I'm trying to add an order by clause to just one of my ActiveRecord queries as follows:
$result = $this->db->get('mytable');
$this->db->order_by('age', 'ASC');
It works, however I get errors because the order by clause is being applied to all my other queries and I get errors because my age column is not present in all tables.
So how do it limit $this->db->order_by('age', 'ASC') to just that one specific query?
Thanks.
You should have $this->db->order_by(); before $result = $this->db->get('mytable');
It should be in this format
$this->db->where("tablename.column", $task_id);
$this->db->order_by('tablename.column', 'ASC'); // or 'DESC'
$this->db->from('table');

Categories