【问题标题】:Android Room SQL Query - How can I run a query with a conditional WHERE clauseAndroid Room SQL 查询 - 如何使用条件 WHERE 子句运行查询
【发布时间】:2020-05-09 11:06:51
【问题描述】:

所以我想运行一个从多个表中获取值的 SQL 查询。 我希望得到:

  • 练习表中的练习名称和练习 ID
  • 来自 exercise_junction_table 的junctionID
  • executive_workout_goals 表中的 setNumber、minReps、maxReps

然后我还有一个 log_entries_table。

此表存储有关用户已记录的锻炼的信息。 如果有的话,我希望从这个表中获取特定日期的所有日志的 COUNT。

如果该日期没有日志,我希望返回值为 0。

ER diagram

从我的研究看来,我似乎需要某种条件 WHERE 子句,但前提是 log_entry 在传递给它的日期存在。

如果没有日志,我只想忽略 WHERE date = :date 部分。

目前,由于我的WHERE date = :date,我的查询仅返回存在 logEntry 的结果 (日期是从 log_Entries 表中获取的,因此如果日志不存在,则根本不会有任何日期。

我无法练习如何使 WHERE date = :date 成为条件变量,并且只能在至少存在一个 logEntry 的练习中运行它。

任何帮助将不胜感激。

我当前的查询(仅返回在其传递日期存在 logEntry 的值。)

 @Query("SELECT exercises_table.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_id, COUNT(log_id) 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 JOIN log_entries_table ON 

exercise_workout_junction_table.exercise_workout_id = 

log_entries_table.junction_id WHERE exercise_workout_junction_table.workout_id = 

:button_id AND log_entries_table.date = :date  ORDER BY 

exercise_workout_goals_table.junction_id; ")

  LiveData<List<ExerciseAndGoal>> getAllWorkoutExercises(int button_id, String date);

练习和目标实体

(这包含我想要获取的所有字段)

public class ExerciseAndGoal {

    private String exercise_name;
    private int set_number;
    private int min_reps;
    private int max_reps;
    private int exercises_id;
    private int junction_id;

    private int log_id;

    private int logs_today;


    public String getExercise_name() {
        return exercise_name;
    }

    public void setExercise_name(String exercise_name) {
        this.exercise_name = exercise_name;
    }

    public int getSet_number() {
        return set_number;
    }

    public void setSet_number(int set_number) {
        this.set_number = set_number;
    }

    public int getMin_reps() {
        return min_reps;
    }

    public void setMin_reps(int min_reps) {
        this.min_reps = min_reps;
    }

    public int getMax_reps() {
        return max_reps;
    }

    public void setMax_reps(int max_reps) {
        this.max_reps = max_reps;
    }

    public int getExercises_id() {
        return exercises_id;
    }

    public void setExercises_id(int exercises_id) {
        this.exercises_id = exercises_id;
    }

    public int getJunction_id() {
        return junction_id;
    }

    public void setJunction_id(int junction_id) {
        this.junction_id = junction_id;
    }



    public int getLog_id() {
        return log_id;
    }

    public void setLog_id(int log_id) {
        this.log_id = log_id;
    }

    public int getLogs_today() {
        return logs_today;
    }

    public void setLogs_today(int logs_today) {
        this.logs_today = logs_today;
    }
}

【问题讨论】:

  • 可能是“AND (log_entries_table.date = :date OR log_entries_table.date 为 NULL)”?
  • 我刚刚尝试过,查询仍然只返回存在 log_entry 的值。

标签: android sql sqlite android-sqlite android-room


【解决方案1】:

你在最后一个子句中只使用“JOIN”,它等于“INNER JOIN”。

这个“INNER JOIN”会从结果中排除条件为假的行:

exercise_workout_junction_table.exercise_workout_id = log_entries_table.junction_id

用“LEFT JOIN”和我在评论中写的修改替换你的最后一个“JOIN”:

AND (log_entries_table.date = :date OR log_entries_table.date is NULL)

【讨论】:

  • 非常感谢,这几乎可以工作了。然而,它似乎只返回 1 个结果。查询中是否有任何可能导致此问题的内容?
  • 不,我看不到任何明显的问题。尝试在某些数据库浏览器中分析查询结果,例如 sqlite [DB Browser] (medium.com/@mattyskala/…)。常见的方法 - 一个一个地摆脱 WHERE 条件(你没有很多),从而检测导致问题的条件
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 1970-01-01
  • 2012-04-20
  • 2020-05-31
  • 1970-01-01
相关资源
最近更新 更多