かなり興味深い状況があります。アドレスとメッセージでいっぱいの SQLite データベースがあります (アドレスは一意ではありません。メッセージは一意です)。各メッセージには日付も関連付けられています。私がやりたいことは、最初のメッセージのアドレス、メッセージ、日付、およびアドレスに関連付けられているメッセージの数を選択することです。
そこで、「アドレスごとにグループ化して、アドレスごとに 1 つのメッセージだけを取得し、日付でこれらを並べ替えて、アドレス列の COUNT を取得することもできる」と考えました。
私はそれをしました、そしてそれはうまくいきます...ちょっと。正しいカウントを取得し、アドレスごとに 1 つのメッセージのみを取得し、日付順に並べ替えますが、アドレスの最新のメッセージは選択しません。任意のようです。
例として、アドレス Y からの 3 つのメッセージ (古いものから最新のものへ) A、B、C と、アドレス Z からの 3 つのメッセージ 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"
、それらは日付でソートされますが、もちろん、グループ化されているのではなく、すべて個別です (日付が異なるため)。
Google 検索は役に立たないことが判明しました。「 android sqlite order before group」や「android sqlite group by order 」などのクエリでは、関連する結果は得られません。
句を削除せずに (これに依存しているため) 、アドレスごとに最新のメッセージを 1 つ選択するにはどうすればよいですか? 2 つのクエリが必要ですか?GROUP
COUNT()
編集: @Adrianがコメントで私にリンクした回答に基づいて、同じ結果を生成する2つのクエリを思いつきました。カウントが 7 (アドレスごとのメッセージではなく、アドレスの総数) であり、表示されたアドレスは最新のメッセージのアドレスではありませんでした。
2 つのクエリは次のとおりです。
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
);