MySQL组通过使用MAX错误的结果



我正在尝试为用户获取每次对话的最新消息。但是,我的分组查询似乎没有返回正确的行。这是我的数据:

ID | MESSAGE | RELATED_ID | DATE_SENT
 2 | Hi      |     2      | 2013-02-21 16:03:00
 3 | Hii     |     2      | 2013-02-21 16:04:00
 4 | Hiii    |     2      | 2013-02-21 16:05:00
 5 | Hiiii   |     2      | 2013-02-21 16:06:00
 6 | Bye     |     6      | 2013-02-21 16:03:01
 7 | Byee    |     6      | 2013-02-21 16:04:01
 8 | Byeee   |     6      | 2013-02-21 16:05:01
 9 | Again   |     9      | 2013-02-21 16:03:02
 10| Againn  |     9      | 2013-02-21 16:04:02

我正在寻找的结果是:

ID | MESSAGE | RELATED_ID | DATE_SENT
 5 | Hiiii   |     2      | 2013-02-21 16:06:00
 8 | Byeee   |     6      | 2013-02-21 16:05:01
 10| Againn  |     9      | 2013-02-21 16:04:02

我当前的查询是:

 SELECT MAX(ID), Message, Date_Sent, related_id FROM MESSAGES GROUP BY RELATED_ID LIMIT 0,100

我得到的结果是:

ID | MESSAGE | RELATED_ID | DATE_SENT
 5 | Hi      |     2      | 2013-02-21 16:03:00
 8 | Bye     |     6      | 2013-02-21 16:03:01
 10| Again   |     9      | 2013-02-21 16:03:02

它似乎得到了正确的ID,但没有得到该ID的正确数据。

如果我能在这方面得到任何帮助,我将不胜感激。

您需要使用子查询为每个related_id选择max(id),然后将其加入到您的表中:

select m1.id,
  m1.message,
  m1.related_id,
  m1.date_sent
from messages m1
inner join
(
  select max(id) MaxId, related_id
  from messages
  group by related_id
) m2
  on m1.id = m2.MaxId
  and m1.related_id = m2.related_id
LIMIT 0,100

请参阅SQL Fiddle with Demo。这样做可以确保为SELECT列表中的其他列返回正确的值。当您不GROUP BY或聚合SELECT列表中的所有项时,MySQL会选择其他列的值,您可能会得到意外的结果。(请参阅MySQL对GROUP BY的扩展)

从MySQL文档:

MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列。。。使用此功能可以避免不必要的列排序和分组,从而获得更好的性能。但是,这主要在GROUP BY中未命名的每个非聚合列中的所有值对于每个组都相同时有用。服务器可以自由地从每个组中选择任何值,因此除非它们相同,否则所选的值是不确定的。此外,从每个组中选择值不能受到添加ORDERBY子句的影响。结果集的排序发生在选择了值之后,ORDERBY不会影响服务器选择的值。

也许它应该是这样的

MAX(Date_Sent) 替换MAX(ID)

最新更新