我正在学习Laravel,我在加入三个表时使用的是DB类。我可以加入三个表格,但我需要得到一个老师的某个专栏的平均值(评级表,评级栏),这里有我的内容,我被困在这里。
这是我的桌面设计
这是我的查询
$teachers = DB::table('ratings as r')
->join('users as u','r.teacher_id', '=', 'u.id')
->join('user_infos as ui','r.teacher_id', '=', 'ui.user_id')
->select('r.rating','ui.about','ui.first_name','ui.last_name','ui.avatar','ui.rate','u.*')
->where('u.status', 1)->get();
此外,正在重复同一用户的结果。用户在评级表中有两个评级,在我看来它会出现两次。
我想在这里显示的是所有教师和每张卡片的清单,以及相应的评分..所以,如果我在桌子上有两位老师,它将显示两位老师,并在右侧的卡是他们的评级。
答案 0 :(得分:1)
这是一个可能的解决方案:
$teachers = DB::table('ratings as r')
->join('users as u','r.teacher_id', '=', 'u.id')
->join('user_infos as ui','r.teacher_id', '=', 'ui.user_id')
->select(DB::raw('AVG(r.rating) as average_rating'),'ui.about','ui.first_name','ui.last_name','ui.avatar','ui.rate','u.*')
->groupBy('r.teacher_id')
->where('u.status', 1)->get();
答案 1 :(得分:1)
好的..既然您正在使用Laravel命名约定/推荐,我认为如果您使用Eloquent会更容易/更清洁。
我不确定你是否已经创建了Eloquent模型。而且,正因为如此,我会把所有东西放在这里(模型等)。
评分模型
class Rating extends Model
{
protected $guard = ['id'];
public function teacher()
{
return $this->belongsTo(User::class, 'teacher_id');
}
public function student()
{
return $this->belongsTo(User::class, 'student_id');
}
}
用户信息模型
class UserInfo extends Model
{
protected $guard = ['id'];
public function user()
{
return $this->belongsTo(User::class);
}
}
用户模型
class User extends Model
{
protected $guard = ['id'];
public function ratings()
{
return $this->hasMany(Rating::class, 'teacher_id');
}
public function infos()
{
return $this->hasMany(UserInfo::class);
}
}
针对您的问题的可能的查询解决方案:
$ratings = Rating::with(['teacher.infos', 'student.infos'])->whereHas('teacher', function($q) {
$q->where('status', true);
})->get();
这可能会给你这样的东西:
// ratings: [
// "id": 1,
// "teacher_id": 1,
// "student_id": 2,
// ....
// "teacher": {
// "id": 1,
// "name": "...."
// ...
// "infos": [{
// "id": 1,
// "skype": '....'
// ....
// }]
// },
// "student": {
// "id": 2,
// "name": ....,
// "infos": [{
// "id": ...
// }]
// }
// ]
现在你有一系列评分。而且,如果您需要访问用户或用户信息,您只需要
// Example:
$firstStudentInfo = $ratings->isEmpty() ? null : $ratings->first()->student->infos;
如果您需要计算某些内容,可以使用额外的查询(db)或只使用一种方法 采集。我认为,在这种情况下,集合可以更快。您还可以创建特定集合 为你的"评级"模型,具体计算(" RatingsCollection")。
另一个例子(刀片模板)。由于我们已经加载了所有东西并且急切负载,我们不必担心 这里有N + 1个查询问题。 (https://laravel.com/docs/5.5/eloquent-relationships#eager-loading)
// Ratings grouped by teacher
@foreach ($ratings->groupBy('teacher') as $rating)
Teacher: {{ $rating->avg()...}} or whatever..
@endforeach
如果你仍然想使用数据库,那么@Md Mahfuzur Rahman会做到这一点。
:)