我有一个相当有趣的情况。我有一个充满地址和消息的 SQLite 数据库(地址不是唯一的;消息是)。每条消息还有一个与之关联的日期。我要做的是选择第一条消息的地址、消息、日期以及与该地址关联的消息数量。
所以,我想,“我可以按地址分组,每个地址只收到一条消息,然后按日期排序,并获取地址列的 COUNT。”
我做到了,它的工作原理......有点。它获取正确的计数,每个地址仅获取一条消息,并按日期对它们进行排序——但它不选择地址的最新消息。这似乎是任意的。
例如,我有来自地址 Y 的三条消息(从最早到最新)A、B、C,以及来自地址 Z 的三条消息 D、E、F。查询可能会获取消息 B 和 E,然后按日期对它们进行排序。它应该获取消息 C 和 F,并按日期对它们进行排序。
这是我到目前为止所拥有的:
// Expanded version:
Cursor cursor = db.query(
/* FROM */ "messages_database",
/* SELECT */ new String[]{ "*", "COUNT(address) AS count" },
/* WHERE */ null,
/* WHERE args */ null,
/* GROUP BY */ "address",
/* HAVING */ null,
/* ORDER BY */ "date DESC"
);
// Or, same code on one line:
Cursor cursor = db.query("messages_database", new String[]{ "*", "COUNT(address) AS count" }, null, null, "address", null, "date DESC");
我觉得这可能与HAVING
条款有关,但我真的不知道。我在 PHP 中经常使用 MySQL,但以前从未接触过HAVING
。我尝试将我的HAVING
子句设置为"MAX(date)"
,但没有效果。如果我将我的GROUP BY
子句设置为"address, date"
,那么它们按日期排序,但当然它们都是单独的而不是分组的(因为日期不同)。
谷歌搜索被证明是徒劳的;像“ android sqlite order before group ”和“ android sqlite group by order ”这样的查询不会产生相关结果。
如何在不删除我的子句的情况下为每个地址选择一条最新消息(依赖于此)?我需要两个查询吗?GROUP
COUNT()
编辑:根据@Adrian 在评论中链接我的答案,我想出了两个查询,它们都产生了相同的结果;一行,其中计数为 7(这是地址的总数,而不是每个地址的消息),并且显示的地址不是最新消息的地址。
这两个查询是:
Cursor cursor = db.rawQuery(
"SELECT t.*, COUNT(t.message_content) AS count "
+ "FROM messages_database t "
+ "INNER JOIN ("
+ " SELECT address, MAX(date) AS maxdate "
+ " FROM messages_database "
+ " GROUP BY address "
+ ") ss ON t.address = ss.address AND t.date = ss.maxdate",
null
);
Cursor cursor = db.rawQuery(
"SELECT t1.*, COUNT(t1.message_content) AS count "
+ "FROM messages_database t1 "
+ "LEFT OUTER JOIN messages_database t2 "
+ "ON (t1.address = t2.address AND t1.date < t2.date) "
+ "WHERE t2.address IS NULL",
null
);