Reputation: 66430
Assume I have table exection_records
which has the data:
+----+----------+---------------------+
| id | handle | finishedAt |
+----+----------+---------------------+
| 1 | task_foo | 2015-08-16 03:10:33 |
| 2 | task_foo | 2015-08-15 04:00:27 |
| 3 | task_foo | 2015-08-14 02:10:25 |
| 4 | task_bar | 2015-08-17 03:00:25 |
| 5 | task_bar | 2015-08-16 02:01:25 |
| 6 | task_bar | 2015-08-13 06:02:50 |
+----+----------+---------------------+
Now I want to get the row where finishedAt
at is at its most recent timestamp for each unique handle, that is:
+----+----------+---------------------+
| id | handle | finishedAt |
+----+----------+---------------------+
| 1 | task_foo | 2015-08-16 03:01:33 |
| 4 | task_bar | 2015-08-17 03:00:25 |
+----+----------+---------------------+
I know that there is MAX
in MySQL.
I could get the very latest record for each task via:
SELECT *,MAX(finishedAt) FROM db.execution_records where taskHandle = 'task_foo';
SELECT *,MAX(finishedAt) FROM db.execution_records where taskHandle = 'task_bar';
Yet I do not want to issue multiple queries but one, and I do not want to name the handles.
How could I achieve my query?
Upvotes: 0
Views: 76
Reputation: 18024
select id, handle, max(finishedAt) from exection_records group by handle;
Here is the output
create table exection_records (id INT, handle VARCHAR(20), finishedAt BIGINT);
insert into exection_records values(1, 'a', 10);
insert into exection_records values(2, 'a', 20);
insert into exection_records values(3, 'a', 30);
insert into exection_records values(4, 'b', 15);
insert into exection_records values(5, 'b', 25);
insert into exection_records values(6, 'b', 35);
select id, handle, max(finishedAt) from exection_records group by handle;
id handle max(finishedAt)
1 a 30
4 b 35
Upvotes: 0
Reputation: 86706
In MySQL, the simplest way is to have a sub-query that finds the last finished time for each handle, then join those results back on to your table to pick out the whole row.
SELECT
execution_records.*
FROM
(
SELECT
handle, MAX(finished_at) AS max_finished_at
FROM
execution_records
GROUP BY
handle
)
AS summary
INNER JOIN
execution_records
ON execution_records.handle = summary.handle
AND execution_records.finished_at = summary.max_finished_at
You can still filter this down to specific handles (rather than all of them) with a simple WHERE
clause.
WHERE
summary.handle IN ('task_foo','task_bah')
The optimiser will then use macro-like-expansion to push that where clause down in to your aggregate query, as well as the outer query.
Upvotes: 1
Reputation: 26143
select *
from exection_records
join (select handle, max(finishedAt) max
from exection_records
group by handle) m
on exection_records.finishedAt=max
Upvotes: 0