Reputation: 489
i'm having hard time getting the right query for this in laravel.
I have table Exams.
id | exam_name
---|------------
1 | First Exam
2 | Second Exam
3 | Third Exam
And Students score table
id | exam_id | score
----|---------|-------
1 | 1 | 15
2 | 1 | 12
3 | 1 | 10
4 | 2 | 7
5 | 2 | 16
6 | 2 | 13
And i want to get the average scores for all exams that looks like
exam_name | average_score
------------|--------------
First Exam | 12.33
Second Exam | 12
Third Exam | 0 or NULL
I have tried left join but it returns multiple rows per exam. I can also think of using nested Query but don't know how it works in Laravel.
Upvotes: 0
Views: 297
Reputation: 1
You don't need to join tables at all. You can solve this with plain laravel.
// in your controller
$exams = Exam::with('students')->get();
// in your view you should replace this with blade
foreach ($exams as $exam) {
$exam->students->avg('score'); // Average score for each exam
}
Your exam model should have:
public function students()
{
return $this->hasMany(student::class);
}
and your students class must have the inverse relation:
public function exam() {
return $this->belongsTo(exam::class);
}
Upvotes: 0
Reputation: 50173
Do the left join
with Students
table :
select e.exam_name, avg(s.score) avg_score
from Exams e
left join Students s on s.exam_id = e.id
group by e.exam_name;
You can also use subquery
with correlation approach
select *,
(select avg(s.score) from Students where e.exam_id = id) avg_score
from Exams e;
Upvotes: 0
Reputation: 15971
DB::table('exams')
->leftJoin('student_score','exam_id','=','exams.id')
->select('exam_name', DB::raw('AVG(score) as average_score'))
->groupBy('exam_name')->get();
You can get the AVG score by using above query.
Hope this helps.
Upvotes: 2