Reputation: 22010
I have a table with data like this:
+-----------+-------+------+----------+
| timestamp | event | data | moreData |
+-----------+-------+------+----------+
| 100000000 | 1 | 10 | 20 |
| 100000001 | 1 | 15 | 10 |
| 100000002 | 1 | 30 | 30 |
| 100000003 | 1 | 5 | 50 |
| 100000004 | 2 | 110 | 120 |
| 100000005 | 2 | 115 | 110 |
| 100000006 | 2 | 130 | 130 |
| 100000007 | 2 | 15 | 150 |
+-----------+-------+------+----------+
Now I want to select only the newest rows for each event. So in the end I want to have this result set:
+-----------+-------+------+----------+
| timestamp | event | data | moreData |
+-----------+-------+------+----------+
| 100000003 | 1 | 5 | 50 |
| 100000007 | 2 | 15 | 150 |
+-----------+-------+------+----------+
So far I was not able to do this. In MySQL I can use "GROUP BY event" but then I get some random row from the database, not the newest. ORDER BY doesn't help because the grouping is done before ordering. Using an aggregation like MAX(timestamp) while grouping by event also doesn't help because then the timestamp is the newest but "data" and "moreData" is still from some other random row.
I guess I have to do a sub select so I have to first get the latest timestamp like this:
SELECT MAX(timestamp), event FROM mytable GROUP BY event
and then use the result set to filter a second SELECT, but how? And maybe there is a clever way to do it without a sub select?
Upvotes: 1
Views: 230
Reputation: 13381
AFAIK, sub select is your best option, as follows:
SELECT *
FROM mytable mt
JOIN ( SELECT MAX(timestamp) as max, event
FROM mytable
GROUP BY event) m_mt
ON (mt.timestamp = m_mt.max AND mt.event = m_mt.event);
Upvotes: 2
Reputation: 39055
SELECT * FROM
(SELECT * FROM mytable ORDER BY timestamp DESC) AS T1
GROUP BY event;
Upvotes: 1
Reputation: 99889
SELECT e2.*
FROM events e
JOIN events e2 ON e2.event = e.event AND e2.timestamp = MAX(e2.timestamp)
GROUP BY e.id
Upvotes: 0
Reputation: 238048
You could use an inner join as a filter:
select *
from events e1
join (
select event
, max(timestamp) as maxtimestamp
from events
group by
event
) e2
on e1.event = e2.event
and e1.tiemstamp = e2.maxtimestamp
Upvotes: 2