Mysql 如何使用group BY获取各组的最新记录?

Mysql 如何使用group BY获取各组的最新记录?,mysql,sql,greatest-n-per-group,Mysql,Sql,Greatest N Per Group,假设我有一个名为messages的表,其中包含以下列: id | from_id | to_id | subject | message | timestamp 我只想从每个用户那里获得最新消息,就像你在深入实际线程之前在FaceBook收件箱中看到的那样 此查询似乎使我接近所需的结果: SELECT * FROM messages GROUP BY from_id 但是,查询给我的是每个用户最早的消息,而不是最新的消息 我搞不懂这个 您需要订购它们 SELECT*FROM messages

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

id | from_id | to_id | subject | message | timestamp
我只想从每个用户那里获得最新消息,就像你在深入实际线程之前在FaceBook收件箱中看到的那样

此查询似乎使我接近所需的结果:

SELECT * FROM messages GROUP BY from_id
但是,查询给我的是每个用户最早的消息,而不是最新的消息


我搞不懂这个

您需要订购它们


SELECT*FROM messages GROUP BY FROM\u id ORDER BY timestamp DESC LIMIT 1

您应该找出每个组(子查询)中的最后一个
时间戳
值,然后将此子查询连接到表中-

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;

这是一个标准问题

请注意,MySQL允许您省略GROUPBY子句中的列,而标准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

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

下面的代码只是补充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;
“GROUPBY”子句必须在主查询中,因为我们需要首先对“源”重新排序,以获得所需的“分组”,因此:

您好,

试试这个

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

此查询返回每个表单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;
选择m1*
从消息m1向左加入消息m2
ON(m1.Form_id=m2.Form_id和m1.id
@BumbleB2na
限制1
你的意思是?现在你将得到所有消息中的最后一条消息,你需要一个where-conditionoops mysql而不是sql。。。你是right@BumbleB2na:实际上它也是SQL,只是它是MySQL SQL,而不是SQL Server SQL(又名Transact-SQL)。:)它将给您相同的结果,只是获得的结果将按时间戳排序。+1这是一个常见问题,但非常感谢您没有使用MySQLs功能,允许select中的列不在group by中!非常感谢你!我能够毫无问题地加入额外的表。这是一个很好的方法。这非常完美。对于那些不习惯SQL的人(比如我)。如果我没有错,“t1”、“t2”和“timestamp”是别名,因此t2是内部SELECT的结果,而t2.timestamp以MAX(timestamp)列为目标,因此可以在ON语句中的外部SELECT中使用它。也许添加一些“AS”对像我这样的新手会有很好的帮助:)我不喜欢它,我真的想对自己做一个内部连接,而不是隐式子查询;但是子查询似乎是唯一的方法。最新的标准SQL允许您省略
GROUP BY
中的列,并将它们包含在
SELECT
HAVING
子句中,前提是它们在功能上依赖于
GROUP BY
组合,因此只返回确定性结果。(MySQL当然不做这样的检查。)@ypercur不确定这是不是这个地方,但是你有什么好的链接吗。我无法理解为什么选择不在group by中的列会因为依赖group by中的项目而变得具有确定性,我唯一能看到的使其不具有确定性的方法是使用order by。然而,看到例子可能有助于澄清问题。感谢
GROUP BY pk
就是一个简单的例子。我的答案与标准(副本)有联系,我希望答案是完美的。谢谢。这个问题甚至有更好的解决方案。虽然这段代码可以回答这个问题,但最好包含一些上下文,解释它是如何工作的以及何时使用它。从长远来看,只使用代码的答案是没有用的。“选择max(id)FROM messages GROUP BY FROM_id”此内部查询,它首先按用户(FROM_id)对记录/消息进行分组然后拉取最大记录id。然后我们再次查询messages表,从内部查询结果集中仅获取最新的记录/消息。最简单的解决方案Imhot如果您希望基于其他非主键列获取具有最大值的记录,则此解决方案可能不起作用。这是我唯一的解决方法。老实说,此答案未被充分理解。这是唯一一个对我有效的解决方案,因为除了我的自动递增字段之外,我还按照不同的字段分组,并且我必须选择最新的按日期。这个答案帮助我在Hibernate HQL中使用它。其他答案都不起作用,因为Hibernate只支持WHERE和SELECT之后的子查询。因为这个答案根本不使用任何子查询,所以它工作得很好。
    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;