仅选择最新的分组条目

时间:2011-09-04 19:03:49

标签: mysql sql greatest-n-per-group

我有一个包含这样数据的表:

+-----------+-------+------+----------+
| 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,但是如何?也许有一种聪明的方法可以在没有子选择的情况下完成它?

4 个答案:

答案 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