我有一个表名test_results,其中包含列--id,user_id,标记,准确度。
现在我需要根据标记和准确度对它们进行排名,所以我喜欢这个 -
$results= TestResult::orderBy('mark', 'desc')->orderBy('accuracy', 'desc')->get();
所以,在这里我可以轻松找到排名 -
foreach($results as $index => $result)
<li>{{$result->user->name}} (Rank - {{$index + 1}}) </li>
但是如何在不获取所有recods的情况下找到排名。对于前
$result = TestResult::findOrFail($id);
如何找到此结果的排名。
排名因素与上述相同。
答案 0 :(得分:0)
您可以在原始查询中使用同一个表的LEFT JOIN,并计算在您选择的行之前排序的所有行:
$result = ModelName::hydrateRaw("
select t1.*, count(t2.id) + 1 as rank
from table_name t1
left join table_name t2
on t2.mark > t1.mark
or t2.mark = t1.mark and t2.accuracy > t1.accuracy
where t1.id = ?
group by t1.id
", [$id])->first();
然后您可以使用$result->rank
访问排名。
请注意,这不会处理关系(t2.mark = t1.mark
和t2.accuracy = t1.accuracy
时)。因此,如果关系是可能的,您应该使用唯一键对它们进行排序(主键应该没问题)。然后ON子句将是
on t2.mark > t1.mark
or t2.mark = t1.mark and t2.accuracy > t1.accuracy
or t2.mark = t1.mark and t2.accuracy = t1.accuracy and t2.id > t1.id
但您还应将原始查询调整为:
$results = TestResult::orderBy('mark', 'desc')
->orderBy('accuracy', 'desc')
->orderBy('id', 'desc')
->get();
演示:http://rextester.com/WMUJ37627
另请注意,您可以比较MySQL中的元组,而您的ON子句也可以
on (t2.mark, t2.accuracy, t2.id) > (t1.mark, t1.accuracy, t1.id)
但MySQL可能无法针对索引使用进行优化。
在版本5.4中hydrateRaw()
已重命名为fromQuery()
。