Android Room LiveData列表仅返回单条数据的问题排查与解决
Room多表按日期分组查询仅返回1条结果的问题解决
我刚踩过类似的坑,你的问题核心在于SQLite对时间戳的解析规则和你存储的毫秒级时间戳不匹配,直接导致分组逻辑完全失效了。
问题现象
- 编写了按日期分组查询14天时间范围数据的语句,预期返回14条结果,但Room实际仅返回1条
- 返回结果里只有
mTimestamp和mAppUsageTime有值,关联查询的mSteps和mEmotionAvg字段全为空
排查过程
- 按照Room规范创建测试表并插入数据后,把SQL语句拿到SQLite在线工具测试是正常的,但放到Room的Dao实现里运行就出了异常
- 调试时发现返回的Cursor长度始终为1,说明分组逻辑根本没按预期拆分数据
问题根源
你的数据库里存储的是毫秒级timestamp(long类型),但SQLite的date()函数默认只识别秒级Unix时间戳。直接用date(timestamp)的话,毫秒级时间戳会被当作超大数值解析,最终所有记录的date(timestamp)结果都是同一个无效日期,自然被归为一组;同时关联查询的日期匹配条件完全不成立,所以mSteps和mEmotionAvg都返回空值。
解决方案
在使用date()函数时,需要把毫秒级时间戳除以1000转成秒级,同时加上'unixepoch'参数告诉SQLite这是Unix时间戳格式。还要注意把GROUP BY子句里的日期规则也同步修正,确保分组逻辑和关联查询的日期判断一致。修正后的Dao代码如下:
@Dao @TypeConverters({DateConverter.class}) public interface SummaryDao { @Query("SELECT MAX(timestamp) as 'mTimestamp', " + "TOTAL(usage_time_in_seconds) as 'mAppUsageTime', " + "(SELECT TOTAL(step_count) FROM StepCountEntity WHERE date(timestamp/1000, 'unixepoch') = date(aue.timestamp/1000, 'unixepoch')) as 'mSteps', " + "(SELECT CASE WHEN AVG(value) IS NULL THEN 0.0 ELSE AVG(value) END FROM EmotionEntity WHERE date(timestamp/1000, 'unixepoch') = date(aue.timestamp/1000, 'unixepoch')) as 'mEmotionAvg' " + "FROM AppUsageEntity aue " + "WHERE timestamp BETWEEN :dateFrom AND :dateTo " + "GROUP BY date(timestamp/1000, 'unixepoch') " + "ORDER BY timestamp DESC") LiveData<List<SummaryEntity>> getSummaries(Date dateFrom, Date dateTo); }
内容的提问来源于stack exchange,提问作者FHellmann
相关产品推荐
相关产品推荐

