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