多对多关系中,如何获取组模型关联的所有科目?
嘿,这需求挺常见的,咱们直接上解决方案!要拿到某个组对应的所有科目,核心就是把几张表的关联关系串起来,同时记得去重(毕竟同一个科目可能被组里多个学生选修)。我给你准备了两种常用的实现方式:
1. 原生SQL写法
如果直接写SQL的话,用JOIN把所有关联表连起来,再通过DISTINCT去重就能得到结果:
SELECT DISTINCT s.subject_id, s.subject_name -- 这里替换成你实际的科目字段 FROM `group` g JOIN student st ON g.group_id = st.group_id JOIN student_subject ss ON st.student_id = ss.student_id JOIN subject s ON ss.subject_id = s.subject_id WHERE g.group_id = [你的目标组ID]; -- 替换成你要查询的组ID
解释一下:咱们从group表出发,先关联到该组下的所有学生,再通过中间表student_subject关联到对应的科目,最后用DISTINCT确保同一个科目只出现一次。
2. Laravel Eloquent ORM写法(如果用PHP框架的话)
假设你已经在模型里定义好了关联关系:
- 在
Group模型里,关联学生:
public function students() { return $this->hasMany(Student::class, 'group_id'); }
- 在
Student模型里,关联科目(多对多):
public function subjects() { return $this->belongsToMany(Subject::class, 'student_subject', 'student_id', 'subject_id'); }
那你可以用两种方式查询:
方式A:先拿学生再取科目(简单直观)
$group = Group::find($groupId); // 获取该组所有学生的所有科目,去重 $subjects = $group->students()->with('subjects')->get() ->pluck('subjects') ->flatten() ->unique('subject_id');
方式B:直接查询科目(更高效,避免N+1问题)
如果追求性能,直接通过关联查询科目:
$subjects = Subject::whereHas('students', function ($query) use ($groupId) { $query->whereHas('group', function ($query) use ($groupId) { $query->where('group_id', $groupId); }); })->distinct()->get();
或者用JOIN的方式:
$subjects = Subject::join('student_subject', 'subjects.subject_id', '=', 'student_subject.subject_id') ->join('student', 'student_subject.student_id', '=', 'student.student_id') ->where('student.group_id', $groupId) ->distinct() ->select('subjects.*') ->get();
不管用哪种方式,核心都是利用表之间的关联关系层层过滤,同时记得去重,避免重复的科目结果~
内容的提问来源于stack exchange,提问作者John Patrick Teruel
相关产品推荐
相关产品推荐

