我有一个包含这样数据的表:
+-----------+-------+------+----------+
| 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 |
+-----------+-------+------+----------+
现在我想只为每个事件选择最新的行。所以最后我想要这个结果集:
+-----------+-------+------+----------+
| timestamp | event | data | moreData |
+-----------+-------+------+----------+
| 100000003 | 1 | 5 | 50 |
| 100000007 | 2 | 15 | 150 |
+-----------+-------+------+----------+
到目前为止,我无法做到这一点。在MySQL中我可以使用“GROUP BY事件”,但后来我从数据库中得到一些随机行,而不是最新的。 ORDER BY没有帮助,因为分组是在订购之前完成的。在按事件分组时使用MAX(时间戳)等聚合也无济于事,因为时间戳是最新的,但“data”和“moreData”仍来自其他一些随机行。
我想我必须做一个子选择,所以我必须先得到这样的最新时间戳:
SELECT MAX(timestamp), event FROM mytable GROUP BY event
然后使用结果集来过滤第二个SELECT,但是如何?也许有一种聪明的方法可以在没有子选择的情况下完成它?
答案 0 :(得分:2)
AFAIK,sub select是您的最佳选择,如下所示:
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);
答案 1 :(得分:2)
您可以使用内部联接作为过滤器:
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
答案 2 :(得分:1)
SELECT * FROM
(SELECT * FROM mytable ORDER BY timestamp DESC) AS T1
GROUP BY event;
答案 3 :(得分:0)
SELECT e2.*
FROM events e
JOIN events e2 ON e2.event = e.event AND e2.timestamp = MAX(e2.timestamp)
GROUP BY e.id