SQLite查询:为每个不同的联系人选择最新的行

时间:2011-09-18 02:38:18

标签: android sql sqlite

我正在使用Android SQLite数据库,我有一个包含消息的表。每封邮件都有一个ContactId。我需要获取与每个ContactId相关联的最新消息的列表。

到目前为止,我的查询看起来像这样:

SELECT * FROM messages GROUP_BY ContactId HAVING ( COUNT(ContactId) = 1 ) ORDER_BY MessageTime DESC

然而,当我运行查询时,我得到了这个例外:

near "ContactId": syntax error: , while compiling: SELECT * FROM messages GROUP_BY ContactId HAVING ( COUNT(ContactId) = 1 ) ORDER_BY MessageTime DESC

以下是表格定义,如果它有帮助:

create table messages (_id integer primary key autoincrement, ContactId text not null, ContactName text not null, ContactNumber text not null, isFrom int not null, Message text not null, MessageTime int not null);

2 个答案:

答案 0 :(得分:2)

注意:我的答案似乎不适用于SQLite 3.7.5,我建议使用Larry建议的“JOIN”查询。

你很亲密。您需要做的是首先使用子查询表对所有记录进行排序,然后对它们进行分组。结果集中返回的值将来自每个组的最后一行。因此,如果您尝试获取新设置的消息,实际上您希望更新的消息显示在底部。 “GROUP BY”已确保每个ContactId获得一行。

SELECT * FROM (SELECT * FROM messages ORDER BY MessageTime) GROUP BY ContactId

不需要HAVING子句。我之前没有使用它,但根据文档,HAVING子句将丢弃不匹配的整个组,但听起来你不想丢弃任何组,你想要每个ContactId的结果。

另请注意,“ORDER BY”或“GROUP BY”中没有下划线。

答案 1 :(得分:2)

以下是两种方法。

此查询构建每个用户的最近时间列表,然后将其返回到消息表以获取消息信息:

 SELECT M1.* FROM messages M1 JOIN 
   (SELECT ContactId, MAX(MessageTime) AS MessageTime FROM messages GROUP BY ContactId) M2
   ON M1.ContactID = M2.ContactID AND M1.MessageTime = M2.MessageTime;

此查询略有不同。它会查看每条消息,并询问是否存在同一联系人的任何后续消息。如果没有,该行必须是最新的一行:

 SELECT M1.* FROM messages M1
    WHERE NOT EXISTS (SELECT * FROM M2 
      WHERE M2.ContactID = M1.ContactID AND M2.MessageTime > M1.MessageTime)
相关问题