I'm developing with CodeIgniter and I have the following problem:
Let's suposse that I have the following table:
| id | employee | job | date |
|----+--------------+-------------+------------|
| 1 | John | sysadmin | 2017-12-01 |
| 2 | Charles | programmer | 2017-11-24 |
| 3 | Peter | programmer | 2017-11-29 |
| 4 | Chris | g.designer | 2017-06-30 |
| 5 | Paul | web devel. | 2017-10-08 |
| 6 | Maria | g.designer | 2017-11-05 |
| 7 | Abigail | programmer | 2017-09-24 |
I want to make a query that selects all fields, showing only 3 rows where the employees won't repeat the same job and the results must be ordered by date desc, so it would be:
| id | employee | job | date |
|----+--------------+-------------+------------|
| 1 | John | sysadmin | 2017-12-01 |
| 3 | Peter | programmer | 2017-11-29 |
| 6 | Maria | g.designer | 2017-11-05 |
I have found the word DISTINCT, but after many tries, I couldn't make it to work as expected, so I made the following workaround:
for($i=0; $i<$limit; $i++)
{
$this->db->where('employee NOT IN("'. implode($employees, '", "') .'")');
$this->db->order_by('date DESC');
$q = $this->db->get('employees', 1);
$r = !empty($q) ? $q->result() : 0;
$employees[] = $r[0]->employee;
$result[] = $r[0];
}
Which makes the following query and stack the result into an array
SELECT * FROM employees WHERE employee NOT IN (implode($employees)) ORDER BY date DESC LIMIT 1
it works perfectly, but quite dirty, since if I want 3 rows, It will make 3 queries, that is not so bad, but when I change it to 18 rows, it takes too long to load the webpage.
I have tried the functions group_by() and distinct() from CodeIgniter, but it neither worked as I expected.
Any way to achieve it with only 1 query?
Best Answer
Assumptions:
job
anddate
, display the one with the lowestid
web devel.
was accidentally left out of the sample desired outputSample data:
We'll use a derived table to order the data by
job
,date
andid
, and then with the help of some variables (@jname
,@jcount
) we'll find a single employee for each uniquejob
who has themax(date)
:NOTE: While
Bob
andMaria
have the samejob
/date
values (g.designer
/2017-11-05
),Maria
is displayed because she has the lowestid
value.Here's a db-fiddle