积分排名 Laravel 积分相等
Points Ranking in Laravel where points are equal
我正在研究如何正确显示积分排名以显示排行榜。
我目前在我的模式中有以下内容
public function getPointrankAttribute(){
$year = Carbon::parse(Carbon::now())->year;
$pointrank = Points::query()
->select('member_id')->selectRaw('SUM(value) as TotalPoints')
->where('Year','=', $year)
->groupBy('member_id')
->orderByDesc('Totalpoints')
->get();
return $pointrank->search(function($points){
return $points->member_id == $this->id;
}) + 1;
}
这很好用,但是它使用 table 中的行位置来显示排名,因此第一条记录显示为第 1,第二条记录显示为第 2。
但是当成员的总分相同时就会出现问题,因为在这种情况下排名是基于table
中的位置
看下面的例子
|member_id|totalpoints|
| 12 | 20 |
| 3 | 10 |
| 10 | 10 |
| 5 | 5 |
本例基于我目前的解决方案
成员12 = 1,成员3 = 2,成员10 = 3,成员5 = 4
我要的是下面的
成员12 = 1,成员3 = 2,成员10 = 2,成员5 = 4
当我们有超过 1 个成员共享该位置时(如本例中的成员 3 和 10),如果我也可以添加“=”,那就太棒了
提前致谢
要为您的用户获得排名,您需要先将排名分配给不同的总分,使用 laravel 集合助手,您可以创建单独的排名集合,而不管成员 ID,如
$collection =collect(
[
[
"member_id" => 12,
"totalpoints" => 20
],
[
"member_id" => 3,
"totalpoints" => 10
],
[
"member_id" => 10,
"totalpoints" => 10
],
[
"member_id" => 5,
"totalpoints" => 5
],
]
);
$ranks = $collection->unique('totalpoints')
->values()
->mapWithKeys(function ($item, $index) {
return [$item['totalpoints'] => $index + 1];
});
Make sure the original collection should be ordered based on total points.
以上将创建一个数组,其中包含不同的点作为键,值作为基于总点的排名
Array
(
[20] => 1
[10] => 2
[5] => 3
)
现在您可以根据原始集合中的 id 搜索您的成员,并从 ranks 数组中获取他们各自的排名,例如
$id = 10;
$ranks[$collection->firstWhere("member_id", $id)["totalpoints"]];
如果供应商数据库支持 window 函数,如 RANK()
,还有另一种方法可以直接从数据库中获取记录的排名
What I want is the following :Member 12 = 1st, Member 3 = 2nd, Member 10 = 2nd, Member 5 = 4th
要获得您想要的结果,您只需从上面的代码中删除 ->values()
,这样您的结果就不会重新编入索引
$ranks = $collection->unique('totalpoints')
->mapWithKeys(function ($item, $index) {
return [$item['totalpoints'] => $index + 1];
});
Array
(
[20] => 1
[10] => 2
[5] => 4
)
我正在研究如何正确显示积分排名以显示排行榜。
我目前在我的模式中有以下内容
public function getPointrankAttribute(){
$year = Carbon::parse(Carbon::now())->year;
$pointrank = Points::query()
->select('member_id')->selectRaw('SUM(value) as TotalPoints')
->where('Year','=', $year)
->groupBy('member_id')
->orderByDesc('Totalpoints')
->get();
return $pointrank->search(function($points){
return $points->member_id == $this->id;
}) + 1;
}
这很好用,但是它使用 table 中的行位置来显示排名,因此第一条记录显示为第 1,第二条记录显示为第 2。
但是当成员的总分相同时就会出现问题,因为在这种情况下排名是基于table
中的位置看下面的例子
|member_id|totalpoints|
| 12 | 20 |
| 3 | 10 |
| 10 | 10 |
| 5 | 5 |
本例基于我目前的解决方案
成员12 = 1,成员3 = 2,成员10 = 3,成员5 = 4
我要的是下面的
成员12 = 1,成员3 = 2,成员10 = 2,成员5 = 4
当我们有超过 1 个成员共享该位置时(如本例中的成员 3 和 10),如果我也可以添加“=”,那就太棒了
提前致谢
要为您的用户获得排名,您需要先将排名分配给不同的总分,使用 laravel 集合助手,您可以创建单独的排名集合,而不管成员 ID,如
$collection =collect(
[
[
"member_id" => 12,
"totalpoints" => 20
],
[
"member_id" => 3,
"totalpoints" => 10
],
[
"member_id" => 10,
"totalpoints" => 10
],
[
"member_id" => 5,
"totalpoints" => 5
],
]
);
$ranks = $collection->unique('totalpoints')
->values()
->mapWithKeys(function ($item, $index) {
return [$item['totalpoints'] => $index + 1];
});
Make sure the original collection should be ordered based on total points.
以上将创建一个数组,其中包含不同的点作为键,值作为基于总点的排名
Array
(
[20] => 1
[10] => 2
[5] => 3
)
现在您可以根据原始集合中的 id 搜索您的成员,并从 ranks 数组中获取他们各自的排名,例如
$id = 10;
$ranks[$collection->firstWhere("member_id", $id)["totalpoints"]];
如果供应商数据库支持 window 函数,如 RANK()
,还有另一种方法可以直接从数据库中获取记录的排名What I want is the following :Member 12 = 1st, Member 3 = 2nd, Member 10 = 2nd, Member 5 = 4th
要获得您想要的结果,您只需从上面的代码中删除 ->values()
,这样您的结果就不会重新编入索引
$ranks = $collection->unique('totalpoints')
->mapWithKeys(function ($item, $index) {
return [$item['totalpoints'] => $index + 1];
});
Array
(
[20] => 1
[10] => 2
[5] => 4
)