【问题标题】:Way to group sqlite cursor results by formated date column按格式化日期列对 sqlite 游标结果进行分组的方法
【发布时间】:2012-10-08 21:30:08
【问题描述】:

有没有比我将要提出的更简单的方法来对 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);";

一旦数据被记录下来,就会产生类似这样的结果:

但是,对于历史页面,我需要以某种方式将按日期执行的所有移动分组到一行中,其中包含执行移动次数的总和,如下面的屏幕截图所示:

我的想法可能是用一个 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 侦听器,该侦听器会在数据库中查询每个日期的所有项目,因此用户可以看到他们在该日期做了什么动作,但现在主列表视图更重要。

一如既往,提前致谢!

【问题讨论】:

    标签: android sqlite arraylist cursor


    【解决方案1】:

    GROUP BY clause 做你想做的事; date function 也有帮助:

    SELECT COUNT(*), date("Date") FROM BJHistory GROUP BY date("Date")
    

    【讨论】:

    • 谢谢,但这并没有最终将我的结果分组到一个数组中以提供给列表视图。
    【解决方案2】:

    我最终让它与我上面发布的稍作修改的版本一起工作。对于任何感兴趣的人,这是我的代码(可能会有所改进):

    首先,我从表中获取所有唯一日期:

    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]);
    }
    

    然后我的数据库访问类中有一个类,它选择与日期匹配的日期数:

    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. 尽可能优化代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      相关资源
      最近更新 更多