加入3个表并计算列的平均值

时间:2018-01-23 10:30:18

标签: php mysql laravel laravel-5

我正在学习Laravel,我在加入三个表时使用的是DB类。我可以加入三个表格,但我需要得到一个老师的某个专栏的平均值(评级表,评级栏),这里有我的内容,我被困在这里。

这是我的桌面设计

enter image description here

这是我的查询

$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();

此外,正在重复同一用户的结果。用户在评级表中有两个评级,在我看来它会出现两次。

enter image description here

我想在这里显示的是所有教师和每张卡片的清单,以及相应的评分..所以,如果我在桌子上有两位老师,它将显示两位老师,并在右侧的卡是他们的评级。

2 个答案:

答案 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 Ra​​hman会做到这一点。

:)