Tengo dos modelos de Examen y Estudiante, después de que cada estudiante intenta un Examen, las calificaciones obtenidas por él / ella se almacenan en la tabla dinámica exam_user. Necesito clasificar al estudiante según las calificaciones obtenidas.
En este momento estoy usando una solución muy ineficiente para esto, que implica un bucle for. A continuación se muestra la implementación
$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;
}
¿Hay alguna forma de que pueda determinar el rango sin usar un bucle for, simplemente usando el generador de consultas en laravel? Creo que me faltan algunos fundamentos de SQL aquí.
El rango es solo el número de personas que tiene un valor mayor que el tuyo + 1.
Por lo tanto, puede hacer esto:
$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;
También puede poner esto en una consulta:
$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;
También puede considerar hacer su tabla dinámica exam_user
como un modelo real y llamarla de alguna manera Marks
, ya que contiene datos importantes que le gustaría consultar.
Luego puede agregar lo siguiente al Exam
modelo:
Class Exam {
// ...
public function marks() {
$this->hasMany(Marks::class);
}
// ...
}
Esto significa que podría hacer algo como:
$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;
Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.
En caso de infracción, por favor [email protected] Eliminar
Déjame decir algunas palabras