如何使用GROUP BY获取每组中的最新记录?

时间:2012-06-12 15:10:05

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

假设我有一个名为messages的表格,其中包含以下列:

id | from_id | to_id | subject | message | timestamp

我想只收到每个用户的最新消息,就像您在深入了解实际线程之前在FaceBook收件箱中看到的那样。

这个查询似乎让我接近我需要的结果:

SELECT * FROM messages GROUP BY from_id

然而,查询给了我每个用户最早的消息,而不是最新消息。

我无法想出这个。

6 个答案:

答案 0 :(得分:79)

您应该在每个组(子查询)中找到最后timestamp个值,然后将此子查询加入表中 -

SELECT t1.* FROM messages t1
  JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2
    ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp;

答案 1 :(得分:17)

试试这个

SELECT * FROM messages where id in (SELECT max(id) FROM messages GROUP BY from_id ) order by id desc

答案 2 :(得分:3)

此查询返回每个Form_id的最后一条记录:

    SELECT m1.*
     FROM messages m1 LEFT JOIN messages m2
     ON (m1.Form_id = m2.Form_id AND m1.id < m2.id)
     WHERE m2.id IS NULL;

答案 3 :(得分:1)

这是一个标准问题。

请注意,MySQL允许您省略GROUP BY子句中的列,而标准SQL不会这样,但是当您使用MySQL工具时,通常不会获得确定性结果。

SELECT *
  FROM Messages AS M
  JOIN (SELECT To_ID, From_ID, MAX(TimeStamp) AS Most_Recent
          FROM Messages
         WHERE To_ID = 12345678
         GROUP BY From_ID
       ) AS R
    ON R.To_ID = M.To_ID AND R.From_ID = M.From_ID AND R.Most_Recent = M.TimeStamp
 WHERE M.To_ID = 12345678

我在To_ID上添加了一个过滤器,以匹配您可能拥有的内容。查询将在没有它的情况下工作,但一般会返回更多数据。不应该在嵌套查询和外部查询中声明条件(优化器应该自动降低条件),但重复条件并不会有害,如图所示。

答案 4 :(得分:1)

只是补充Devart所说的,下面的代码不是根据问题排序:

SELECT t1.* FROM messages t1
  JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2
    ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp;

&#34; GROUP BY&#34;子句必须在主查询中,因为我们需要首先重新排序&#34; SOURCE&#34;得到所需的&#34;分组&#34;这样:

SELECT t1.* FROM messages t1
  JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages ORDER BY timestamp DESC) t2
    ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp GROUP BY t2.timestamp;

此致

答案 5 :(得分:-5)

您需要订购它们。

SELECT * FROM messages GROUP BY from_id ORDER BY timestamp DESC LIMIT 1