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

Android Room SQL查询:如何实现带条件WHERE子句的查询

解决方法:调整JOIN类型与条件位置,正确统计当日日志数

你的问题核心在于INNER JOIN和WHERE条件的位置导致无当日日志的运动被过滤掉了。我们需要调整关联方式和条件逻辑,确保所有符合workout_id的运动都能返回,同时准确统计指定日期的日志数量(无日志时返回0)。

问题分析

  1. 你当前用了JOIN log_entries_table(默认是INNER JOIN),这会自动过滤掉没有对应日志的运动记录;
  2. WHERE log_entries_table.date = :date进一步筛选出仅当日有日志的记录,完全排除了无当日日志的运动;
  3. 缺少GROUP BY子句,COUNT(log_id)会将所有结果合并为一行,无法按每个运动/目标单独统计。

修改后的SQL查询

@Query("SELECT " +
        "exercises_table.exercise_Name AS exercise_name, " +
        "exercises_table.exercises_id, " +
        "exercise_workout_goals_table.set_number, " +
        "exercise_workout_goals_table.junction_id, " +
        "exercise_workout_goals_table.min_reps, " +
        "exercise_workout_goals_table.max_reps, " +
        "log_entries_table.log_id, " +
        "COUNT(CASE WHEN log_entries_table.date = :date THEN 1 END) AS logs_today " +
        "FROM exercises_table " +
        "LEFT JOIN exercise_workout_junction_table ON exercises_table.exercises_id = exercise_workout_junction_table.exercise_id " +
        "LEFT JOIN exercise_workout_goals_table ON exercise_workout_junction_table.exercise_workout_id = exercise_workout_goals_table.junction_id " +
        "LEFT JOIN log_entries_table ON exercise_workout_junction_table.exercise_workout_id = log_entries_table.junction_id AND log_entries_table.date = :date " +
        "WHERE exercise_workout_junction_table.workout_id = :button_id " +
        "GROUP BY exercises_table.exercises_id, exercise_workout_goals_table.junction_id, exercise_workout_goals_table.set_number " +
        "ORDER BY exercise_workout_goals_table.junction_id; ")
LiveData<List<ExerciseAndGoal>> getAllWorkoutExercises(int button_id, String date);

关键修改点说明

  1. 将INNER JOIN改为LEFT JOIN log_entries_table:确保即使没有对应日志,主表(exercises_table、exercise_workout_goals_table)的记录依然会被返回;
  2. 把日期条件移到LEFT JOIN的ON子句中:这样只会关联指定日期的日志,不会过滤掉无当日日志的主表记录;
  3. 使用COUNT(CASE...)统计当日日志数:当日志日期匹配时计数1,否则忽略,无日志时自然返回0;
  4. 添加GROUP BY子句:按运动ID、目标ID和组数分组,确保每个运动/目标组合单独统计日志数,避免结果合并。

实体类小优化

注意log_id在无日志时会是NULL,建议把实体类中的log_id字段类型从int改为Integer,避免空指针异常:

private Integer log_id; // 替换原来的int log_id

public Integer getLog_id() { return log_id; }
public void setLog_id(Integer log_id) { this.log_id = log_id; }

内容的提问来源于stack exchange,提问作者Josh Brett

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 16:02:28