如何用子查询编写雄辩的左联接?

时间:2019-07-06 07:33:55

标签: php laravel eloquent

我想雄辩地编写一个带有子查询的左联接查询。我有两个表,教训和教训用户。

lesson
lesson_id | name | grade

lesson_user
lesson_id|user_id

如果某个学生正在上一堂课,他的ID将在lesson_user表中。

我想获得一个年级的所有课程,如果用户参加了一个课程,则需要他的ID。

结果将是:对于user_id 5和3年级

 grade   lesson   user_id
   3      java       5
   3      C++        5
   3      Python    NULL  //He is not participating  

在这里,用户ID将作为参数,我尝试了此操作,但是没有用。

public function getAll($grade_id, $user_id)
{
    $lessons = Lesson::where('grade_id', $grade_id);

    if($user_id != null){
        $sub = LessonUser::where('user_id', $user_id);
        $lessons = $lessons->leftJoin(DB::raw("($sub->toSql()) as b"), 'b.lesson_id', '=', 'lesson.id');
     }

     $lessons = $lessons
                  ->select("lesson.id", "lesson.name", "user_id", "grade")
                    ->get();

     return $lessons;
}

PS:每节课都有一个分数。

编辑:

我最初使用此代码,而不是if块中的子查询和代码。但是它给出了无效的结果。它返回不属于年级的课程。

$lessons = $lessons->leftJoin('lesson_user as b', 'b.lesson_id', '=', 'lesson.id');
$lessons = $lessons->where("b.user_id",  $user_id)->orWhereNull("b.user_id");

谢谢:)

1 个答案:

答案 0 :(得分:1)

我的建议是在join子句中使用where('user_id', $user_id),从而使查询更具可读性:

public function getAll($grade_id, $user_id)
{
    return Lesson::query()
        ->leftJoin('lesson_user', function (JoinClause $join) use ($user_id) {
            $join->on('lesson_user.lesson_id', '=', 'lesson.id')
                ->when($user_id !== null, function ($query) use ($user_id) {
                    $query->where('lesson_user.user_id', $user_id);
                });
        })
        ->where('lesson.grade', $grade_id)
        ->select([
            'lesson.id',
            'lesson.name',
            'lesson.grade',
            'lesson_user.user_id',
        ]);
        ->get();
}