You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过单条SQLiteDatabase query()实现多分组求和及总距离统计?

单条SQLite查询实现多维度运动距离统计

你可以通过UNION ALL将三个统计逻辑合并成单条查询,同时添加一个标识字段区分不同的统计维度,无需多次查询。以下是具体实现方案:

1. 编写SQL语句

假设你的表名为sports_data,字段分别是sport_type(运动类型)、distance(距离)、timestamp(时间戳,秒级),可以用下面的SQL:

-- 统计总距离
SELECT '总距离' AS stat_type, NULL AS group_key, SUM(distance) AS total_distance
FROM sports_data
UNION ALL
-- 按运动类型分组统计
SELECT '类型分组' AS stat_type, sport_type AS group_key, SUM(distance) AS total_distance
FROM sports_data
GROUP BY sport_type
UNION ALL
-- 按日期分组统计(将时间戳转为YYYY-MM-DD格式)
SELECT '日期分组' AS stat_type, DATE(timestamp, 'unixepoch') AS group_key, SUM(distance) AS total_distance
FROM sports_data
GROUP BY DATE(timestamp, 'unixepoch')
  • stat_type:标记当前行属于哪种统计结果(总距离/类型分组/日期分组)
  • group_key:存储分组维度的值(运动类型或日期,总距离行设为NULL)
  • total_distance:对应维度的距离总和

2. 在Android中执行查询

SQLiteDatabase.query()更适合单表查询,推荐用rawQuery()执行上述SQL:

String sql = "SELECT '总距离' AS stat_type, NULL AS group_key, SUM(distance) AS total_distance " +
             "FROM sports_data " +
             "UNION ALL " +
             "SELECT '类型分组' AS stat_type, sport_type AS group_key, SUM(distance) AS total_distance " +
             "FROM sports_data " +
             "GROUP BY sport_type " +
             "UNION ALL " +
             "SELECT '日期分组' AS stat_type, DATE(timestamp, 'unixepoch') AS group_key, SUM(distance) AS total_distance " +
             "FROM sports_data " +
             "GROUP BY DATE(timestamp, 'unixepoch')";

Cursor cursor = db.rawQuery(sql, null);

3. 遍历Cursor处理结果

通过stat_type字段判断当前行的统计类型,分别提取对应数据:

if (cursor != null && cursor.moveToFirst()) {
    float totalOverall = 0;
    Map<String, Float> typeStats = new HashMap<>();
    Map<String, Float> dateStats = new HashMap<>();

    do {
        String statType = cursor.getString(cursor.getColumnIndexOrThrow("stat_type"));
        float distance = cursor.getFloat(cursor.getColumnIndexOrThrow("total_distance"));

        switch (statType) {
            case "总距离":
                totalOverall = distance;
                break;
            case "类型分组":
                String sportType = cursor.getString(cursor.getColumnIndexOrThrow("group_key"));
                typeStats.put(sportType, distance);
                break;
            case "日期分组":
                String date = cursor.getString(cursor.getColumnIndexOrThrow("group_key"));
                dateStats.put(date, distance);
                break;
        }
    } while (cursor.moveToNext());

    // 这里可以使用统计好的数据生成报表
    Log.d("Stats", "总距离: " + totalOverall);
    Log.d("Stats", "类型统计: " + typeStats);
    Log.d("Stats", "日期统计: " + dateStats);

    cursor.close();
}

注意事项

  • 如果你的时间戳是毫秒级,需要调整日期转换逻辑:DATE(timestamp / 1000, 'unixepoch')
  • 确保字段名和表名与你的实际数据库一致
  • 若数据量极大,单条UNION查询的性能可能略低于多条单独查询,但日常使用场景下差异可以忽略

内容的提问来源于stack exchange,提问作者Style-7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:25:16