Привет, мне было интересно, можно ли сгруппировать / отсортировать результаты запроса по агрегатным функциям (MAX, MIN, COUNT) с помощью Eloquent Laravel. Модели:
class School extends Model{
function students(){
return $this -> hasMany(Student::class);
}
}
class Student extends Model{
function school(){
return $this -> belongsTo(School::class);
}
}
Классическое отношение один ко многим, и я хочу выполнить следующий запрос:
School::select('school.*', 'MAX(student.score) as best_score') -> join('student', 'student.school_id', '=', 'school.id') -> orderByDesc('best_score') -> toSql()
Поэтому я хочу перечислить все школы, в которых есть ученики с лучшими оценками. Laravel Eloquent выполняет следующий запрос:
select `school`.*, `MAX(student`.`score)` as `best_score` from `serije` inner join `student` on `student`.`school_id` = `school`.`id` order by `best_score` desc
Таким образом, он оказывает MAX(student
как столбец, и это вызывает ошибку SQL, есть ли способ обойти это без использования коллекций, Идея состоит в том, чтобы максимально использовать БД.
Вы можете добавить пользовательский атрибут и сделать orderBy для этого пользовательского атрибута:
class School extends Model
{
public function students()
{
return $this->hasMany(Student::class);
}
public function getHighestScoreAttribute()
{
$student = $this->students()->orderBy('score')->first();
return $student ? $student->score : 0;
}
}
class Student extends Model{
public function school()
{
return $this->belongsTo(School::class);
}
}
// Query
$schools = School::orderBy('highestScore')->all();
Вы можете легко проверить это на модели школы.
public function students(){
return $this->hasMany('App\Student','school_id','id')->orderByDesc('score');
}
Вызовите эту функцию на вашем контроллере с помощью (‘студентов’)