У меня есть значение «оценки» в сводной таблице, как найти рейтинг студента на основе значения «оценки» с помощью построителя запросов? - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть две модели Экзамен и Студент, после того, как каждый студент попытается пройти Экзамен, оценки, полученные им / ею, сохраняются в сводной таблице exam_user.Мне нужно оценивать студента на основе полученных оценок.

Сейчас я использую очень неэффективное решение для этого, которое включает цикл for.Ниже приведена реализация

            $rank=0;
            $attempts = DB::table('exam_user')
                    ->where('exam_id',$exam->id)
                    ->orderBy('marks','desc')
                    ->get();
            foreach ($attempts as $attempt) {
                $rank++;
                if($attempt->user_id==Auth::id())
                    break;
            }

Есть ли способ определить ранг без использования цикла for, просто используя построитель запросов в laravel.Я думаю, что здесь не хватает некоторых основ SQL.

1 Ответ

0 голосов
/ 20 ноября 2018

Ранг - это просто число людей, которые имеют большую ценность, чем ваша + 1.

Поэтому вы можете просто сделать это:

$userMarks = DB::table('exam_user')
    ->select('marks')
    ->where('exam_id', $exam->id)
    ->where('user_id', '=', Auth::id())
    ->firstOrFail()
    ->marks;

$rank = DB::table('exam_user')
    ->where('exam_id', $exam->id)
    ->where('marks', '>', $userMarks)
    ->count() + 1;

Вы также можете поместить это в один запрос:

$userId = Auth::id();
$rank = DB::table('exam_user')
            ->where('exam_id', $exam->id)
            ->whereRaw(
                "marks > (select eu2.marks from exam_user eu2 where eu2.exam_id = {$exam->id} and eu2.user_id = {$userId}) limit 1"
            )
            ->count() + 1;

Вы также можете рассмотреть вопрос о том, чтобы сделать сводную таблицу exam_user реальной моделью, и назвать ее как Marks, поскольку она содержит важные данные, которые вы хотите запросить.

Затем к модели Exam можно добавить следующее:

Class Exam {
    // ...
    public function marks() {
        $this->hasMany(Marks::class);
    }    
    // ...
}

Это означает, что вы можете сделать что-то вроде:

$userId = Auth::id();
$rank = $exam->marks()
            ->whereRaw(
                "marks > (select marks from exam_user where exam_id = {$exam->id} and user_id = {$userId}) limit 1"
            )
            ->count() + 1;
...