1

私が提案しようとしているよりも、SQLite データベースからのデータをグループ化して提示する簡単な方法はありますか? もしそうなら、どのように改善しますか?

私がジム向けに行っているアプリでは、5 種類の運動クラスの履歴を日付別に降順 (上が最新) に記録できる必要があります。よりよく理解するためにコードを共有するという精神で、ここに私のテーブルの作成があります:

private static final String CREATE_TABLE_BJJ = "CREATE TABLE IF NOT EXISTS "
    // TODO finish this
    + TABLE_BJJ + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
    + BJJ_HISTORY_MOVE + " TEXT NOT NULL, " + BJJ_HISTORY_MOVECOUNT + " INTEGER NOT NULL, "
    + BJJ_HISTORY_PERFORMEDBY + " TEXT NOT NULL, " + BJJ_HISTORY_PERFORMEDTO
    + " TEXT NOT NULL, " + DATE + " datetime NOT NULL, " + UPLOADED
    + " INTEGER NOT NULL DEFAULT 0);";

これにより、データが記録されると次のようになります。 テーブルロウ

ただし、履歴ページの場合は、下のスクリーンショットのように、日付ごとに実行されたすべての移動を、実行された移動数の合計で 1 つの行に何らかの方法でグループ化する必要があります。

サンプル画面

私が考えていたのは、配列に SELECT DISTINCT STATEMENTの結果を入力し、次の ように結果を配列に入力することです。

String query ="SELECT DISTINCT Date FROM BJJHistory";
ArrayList<String> dateList = new ArrayList<String>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Cursor  cursor = database.rawQuery(query,null);
if (cursor != null) {
    cursor.moveToFirst();
    if (!cursor.isAfterLast())
    {
         do
         {
              String datestr = sdf.format(new Date(cursor.getString(0))); 
              dateList.add(datestr);
         }
         while (cursor.moveToNext());
    }

}
return cursor;

結果を保持するカスタム クラスがあります。

Public class History {
public String numMoves;
public String date;

public History() {
    super();
}

public History(final String numMoves, final String date) {
    super();
    this.numMoves = numMoves;
    this.date = date;
    }
}

その後、配列を使用してカーソルを作成し、データを次のようにプルします。

final ArrayList<History> BJJHistory = new ArrayList<History>();
for (int i = 0; dateList.size(); i++) {
    final Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM BJJHistory WHERE Date LIKE '" + dateList(i).toString() + "%'") > 0, null); 
    if (cursor != null) {
        cursor.moveToFirst();

        BJJHistory.add(new History(cursor.getString(0).toString(),dateList[i].toString())) 
    }

タイピングが多い

最後に、配列アダプターを使用して、結果の履歴アイテムの配列リストでリストビューを埋めます。各日付のすべてのアイテムをデータベースに照会する onclick リスナーを実装する方法を引き続き使用する必要があります。これにより、ユーザーはその日付に行った動きを確認できますが、現在はメインのリストビューがより重要です。

いつものように、よろしくお願いします!

4

2 に答える 2

1

GROUP BYはあなたが望むことをします。このdate機能は次のことにも役立ちます。

SELECT COUNT(*), date("Date") FROM BJHistory GROUP BY date("Date")
于 2012-10-09T05:27:45.187 に答える
0

上に投稿したものを少し修正したバージョンで動作するようになりました。興味のある人のために、これが私のコードです(おそらく改善される可能性があります):

まず、テーブルから一意の日付をすべて取得します。

public String[] getUniqueDates(final String tablename) {
    final String query = "SELECT DISTINCT Date FROM " + tablename
            + " ORDER BY Date DESC";

    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    final SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    final Cursor cursor = database.rawQuery(query, null);
    String datestr = null;

    final Set<String> set = new LinkedHashSet<String>();
    if (cursor != null) {
        cursor.moveToFirst();
        if (!cursor.isAfterLast()) {
            do {
                // Convert the date to YYYY-MM-DD
                try {
                    final Date dt = sourceFormat.parse(cursor.getString(0));
                    datestr = sdf.format(dt);
                } catch (final ParseException e) {
                    e.printStackTrace();
                }
                set.add(datestr);
            } while (cursor.moveToNext());
        }
        cursor.close();
    }

    return set.toArray(new String[0]);
}

次に、Database Access クラスに、日付に一致する日付の数を選択するクラスがあります。

public String selectCount(final String date) {
    String count = "";
    final Cursor cursor = database.rawQuery("SELECT COUNT(*) FROM "
            + SQLiteHelper.TABLE_BJJ + " WHERE Date LIKE '" + date
            + "%'", null);
    if (cursor != null) {
        cursor.moveToFirst();
        count = cursor.getString(0);
        cursor.close();
    }

    return count;
}

データを ListView に入れる肉とジャガイモ:

String[] DateArray = datasource.getUniqueDates(SQLiteHelper.TABLE_BJJ);
final History BJJHistoryArray[] = new History[DateArray.length];
for (int i = 0; i < DateArray.length; i++) {
    String suffix;
    if (datasource.selectCount(DateArray[i]).equals("1"))
        suffix = " Move";
    else
        suffix = " Moves";
    BJJHistoryArray[i] = new History(datasource.selectCount(DateArray[i]) + suffix,
            DateArray[i]);
}

final HistoryAdapter adapter = new HistoryAdapter(this, R.layout.history_row,
        BJJHistoryArray);
BJJHistory.setAdapter(adapter);

これにより、次の結果が得られます。

スクリーンショット

ログ エントリ ボタンを使用して新しいエントリがログに記録されると、クエリが更新され、1そのたびに数値が変更されます。

改善点:

  1. メソッドのパラメーターを追加して、selectCount()任意のテーブルで使用できるようにします。
  2. 可能であれば、カーソルの最適化を試みてください。
  3. 可能であれば、コードを最適化します。
于 2012-10-09T19:03:30.040 に答える