我想雄辩地编写一个带有子查询的左联接查询。我有两个表,教训和教训用户。
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");
谢谢:)
答案 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();
}