game_instances
表:
id | 用户 ID | 国家 | 地区 | 分数 | 动 | 完成于 |
---|---|---|---|---|---|---|
1 | 1 | 伊朗伊斯兰共和国 | 库姆 | 404 | 71 | 2021-05-14 02:56:10 |
2 | 1 | 伊朗伊斯兰共和国 | 库姆 | 686 | 138 | 2021-05-14 02:58:13 |
3 | 1 | 伊朗伊斯兰共和国 | 库姆 | 空 | 空 | 空 |
4 | 2 | 伊朗伊斯兰共和国 | 亚兹德 | 1162 | 194 | 2021-05-14 03:03:00 |
5 | 2 | 伊朗伊斯兰共和国 | 亚兹德 | 220 | 56 | 2021-05-14 03:04:19 |
6 | 2 | 伊朗伊斯兰共和国 | 亚兹德 | 8 | 5 | 2021-05-14 03:05:13 |
7 | 2 | 伊朗伊斯兰共和国 | 库姆 | 280 | 70 | 2021-05-14 03:06:11 |
8 | 2 | 伊朗伊斯兰共和国 | 库姆 | 空 | 空 | 空 |
9 | 3 | 伊朗伊斯兰共和国 | 库姆 | 570 | 107 | 2021-05-14 03:10:26 |
10 | 3 | 伊朗伊斯兰共和国 | 库姆 | 0 | 0 | 2021-05-14 03:32:40 |
我需要用户的排名号码:
还有这6个细分市场前10名用户的排行榜。我通过 12 个单独的查询获取 12 个数据集。我希望使用 MySQL 5.7 来组合和优化这些。目前实施:
public function leaderboard(Request $request)
{
$user = $request->input('_user');
if (!$user) {
return apiSend(null, 401);
}
$data = [
'total' => [
'player' => [
'score' => 0,
'global_rank' => 0,
'country_rank' => 0,
'region_rank' => 0,
],
'global' => [], 'country' => [], 'region' => [],
],
'high' => [
'player' => [
'score' => 0,
'global_rank' => 0,
'country_rank' => 0,
'region_rank' => 0,
],
'global' => [], 'country' => [], 'region' => [],
],
];
$countryWhereClause = $user->country ? "WHERE country = '{$user->country}'" : 'WHERE country IS NULL';
$regionWhereClause = $user->region ? "AND region = '{$user->region}'" : 'AND region IS NULL';
$totalGlobalRank = DB::select("SELECT t1.user_id, t1.rank, t1.total_score FROM (SELECT p.user_id, p.total_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, SUM(score) AS total_score FROM game_instances GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.total_score DESC) t1 WHERE t1.user_id = {$user->id}");
$totalCountryRank = DB::select("SELECT t1.user_id, t1.rank, t1.total_score FROM (SELECT p.user_id, p.total_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, SUM(score) AS total_score FROM game_instances {$countryWhereClause} GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.total_score DESC) t1 WHERE t1.user_id = {$user->id}");
$totalRegionRank = DB::select("SELECT t1.user_id, t1.rank, t1.total_score FROM (SELECT p.user_id, p.total_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, SUM(score) AS total_score FROM game_instances {$countryWhereClause} {$regionWhereClause} GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.total_score DESC) t1 WHERE t1.user_id = {$user->id}");
$highGlobalRank = DB::select("SELECT t1.user_id, t1.rank, t1.max_score FROM (SELECT p.user_id, p.max_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, MAX(score) AS max_score FROM game_instances GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.max_score DESC) t1 WHERE t1.user_id = {$user->id}");
$highCountryRank = DB::select("SELECT t1.user_id, t1.rank, t1.max_score FROM (SELECT p.user_id, p.max_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, MAX(score) AS max_score FROM game_instances {$countryWhereClause} GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.max_score DESC) t1 WHERE t1.user_id = {$user->id}");
$highRegionRank = DB::select("SELECT t1.user_id, t1.rank, t1.max_score FROM (SELECT p.user_id, p.max_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, MAX(score) AS max_score FROM game_instances {$countryWhereClause} {$regionWhereClause} GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.max_score DESC) t1 WHERE t1.user_id = {$user->id}");
if (count($totalGlobalRank)) {
$data['total']['player']['score'] = $totalGlobalRank[0]->total_score;
$data['total']['player']['global_rank'] = $totalGlobalRank[0]->rank;
}
if (count($totalCountryRank)) {
$data['total']['player']['country_rank'] = $totalCountryRank[0]->rank;
}
if (count($totalRegionRank)) {
$data['total']['player']['region_rank'] = $totalRegionRank[0]->rank;
}
if (count($highGlobalRank)) {
$data['high']['player']['score'] = $highGlobalRank[0]->max_score;
$data['high']['player']['global_rank'] = $highGlobalRank[0]->rank;
}
if (count($highCountryRank)) {
$data['high']['player']['country_rank'] = $highCountryRank[0]->rank;
}
if (count($highRegionRank)) {
$data['high']['player']['region_rank'] = $highRegionRank[0]->rank;
}
$countryWhereClause = $user->country ? "WHERE g.country = '{$user->country}'" : 'WHERE g.country IS NULL';
$regionWhereClause = $user->region ? "AND g.region = '{$user->region}'" : 'AND g.region IS NULL';
$totalGlobalLeaderboards = $this->totalGlobalLeaderboards($user);
$totalCountryLeaderboards = $this->totalCountryLeaderboards($user);
$totalRegionLeaderboards = $this->totalRegionLeaderboards($user);
$highGlobalLeaderboards = $this->highGlobalLeaderboards($user);
$highCountryLeaderboards = $this->highCountryLeaderboards($user);
$highRegionLeaderboards = $this->highRegionLeaderboards($user);
foreach ($totalGlobalLeaderboards as $r) {
$data['total']['global'][] = ['name' => $r->name, 'score' => $r->total_score, 'rank' => $r->rank, 'is_user' => $user->id == $r->user_id];
}
foreach ($totalCountryLeaderboards as $r) {
$data['total']['country'][] = ['name' => $r->name, 'score' => (int) $r->total_score, 'rank' => $r->rank, 'is_user' => $user->id == $r->user_id];
}
foreach ($totalRegionLeaderboards as $r) {
$data['total']['region'][] = ['name' => $r->name, 'score' => (int) $r->total_score, 'rank' => $r->rank, 'is_user' => $user->id == $r->user_id];
}
foreach ($highGlobalLeaderboards as $r) {
$data['high']['global'][] = ['name' => $r->name, 'score' => (int) $r->max_score, 'rank' => $r->rank, 'is_user' => $user->id == $r->user_id];
}
foreach ($highCountryLeaderboards as $r) {
$data['high']['country'][] = ['name' => $r->name, 'score' => (int) $r->max_score, 'rank' => $r->rank, 'is_user' => $user->id == $r->user_id];
}
foreach ($highRegionLeaderboards as $r) {
$data['high']['region'][] = ['name' => $r->name, 'score' => (int) $r->max_score, 'rank' => $r->rank, 'is_user' => $user->id == $r->user_id];
}
return apiSend($data);
}
// Returns leaderboards with ranks near user rank, if user is not in the top 10.
public function userLeaderboards(Request $request)
{
$user = $request->input('_user');
if (!$user) {
return apiSend(null, 401);
}
$rank = (int) $request->query('rank');
$type = $request->query('type');
$scope = $request->query('scope');
if ($rank <= 10) {
return apiSend(null, 400);
}
$data = [];
$rows = [];
switch (true) {
case $type == 'total' && $scope == 'global':
$rows = $this->totalGlobalLeaderboards($user, $rank);
break;
case $type == 'total' && $scope == 'country':
$rows = $this->totalCountryLeaderboards($user, $rank);
break;
case $type == 'total' && $scope == 'region':
$rows = $this->totalRegionLeaderboards($user, $rank);
break;
case $type == 'high' && $scope == 'global':
$rows = $this->highGlobalLeaderboards($user, $rank);
break;
case $type == 'high' && $scope == 'country':
$rows = $this->highCountryLeaderboards($user, $rank);
break;
case $type == 'high' && $scope == 'region':
$rows = $this->highRegionLeaderboards($user, $rank);
break;
default:
return apiSend(null, 400);
}
foreach ($rows as $r) {
$data[] = ['name' => $r->name, 'score' => (int) ($type == 'total' ? $r->total_score : $r->max_score), 'rank' => (int) $r->rank, 'is_user' => $user->id == $r->user_id];
}
return apiSend($data);
}
private function totalGlobalLeaderboards($user, $rank = 0)
{
if (!$user) {
return [];
}
$offset = $rank > 10 ? sprintf('OFFSET %d', $rank - 6) : '';
$rowNumInit = $rank > 10 ? $rank - 6 : 0;
return DB::select("SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, SUM(g.score) AS total_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id GROUP BY user_id ORDER BY total_score DESC LIMIT 10 {$offset}) t, (SELECT @rownum := {$rowNumInit}) r");
}
private function totalCountryLeaderboards($user, $rank = 0)
{
if (!$user) {
return [];
}
$offset = $rank > 10 ? sprintf('OFFSET %d', $rank - 6) : '';
$rowNumInit = $rank > 10 ? $rank - 6 : 0;
$countryWhereClause = $user->country ? "WHERE g.country = '{$user->country}'" : 'WHERE g.country IS NULL';
return DB::select("SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, SUM(g.score) AS total_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id {$countryWhereClause} GROUP BY user_id ORDER BY total_score DESC LIMIT 10 {$offset}) t, (SELECT @rownum := {$rowNumInit}) r");
}
private function totalRegionLeaderboards($user, $rank = 0)
{
if (!$user) {
return [];
}
$offset = $rank > 10 ? sprintf('OFFSET %d', $rank - 6) : '';
$rowNumInit = $rank > 10 ? $rank - 6 : 0;
$countryWhereClause = $user->country ? "WHERE g.country = '{$user->country}'" : 'WHERE g.country IS NULL';
$regionWhereClause = $user->region ? "AND g.region = '{$user->region}'" : 'AND g.region IS NULL';
return DB::select("SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, SUM(g.score) AS total_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id {$countryWhereClause} {$regionWhereClause} GROUP BY user_id ORDER BY total_score DESC LIMIT 10 {$offset}) t, (SELECT @rownum := {$rowNumInit}) r");
}
private function highGlobalLeaderboards($user, $rank = 0)
{
if (!$user) {
return [];
}
$offset = $rank > 10 ? sprintf('OFFSET %d', $rank - 6) : '';
$rowNumInit = $rank > 10 ? $rank - 6 : 0;
return DB::select("SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, MAX(g.score) AS max_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id GROUP BY user_id ORDER BY max_score DESC LIMIT 10 {$offset}) t, (SELECT @rownum := {$rowNumInit}) r");
}
private function highCountryLeaderboards($user, $rank = 0)
{
if (!$user) {
return [];
}
$offset = $rank > 10 ? sprintf('OFFSET %d', $rank - 6) : '';
$rowNumInit = $rank > 10 ? $rank - 6 : 0;
$countryWhereClause = $user->country ? "WHERE g.country = '{$user->country}'" : 'WHERE g.country IS NULL';
return DB::select("SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, MAX(g.score) AS max_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id {$countryWhereClause} GROUP BY user_id ORDER BY max_score DESC LIMIT 10 {$offset}) t, (SELECT @rownum := {$rowNumInit}) r");
}
private function highRegionLeaderboards($user, $rank = 0)
{
if (!$user) {
return [];
}
$offset = $rank > 10 ? sprintf('OFFSET %d', $rank - 6) : '';
$rowNumInit = $rank > 10 ? $rank - 6 : 0;
$countryWhereClause = $user->country ? "WHERE g.country = '{$user->country}'" : 'WHERE g.country IS NULL';
$regionWhereClause = $user->region ? "AND g.region = '{$user->region}'" : 'AND g.region IS NULL';
return DB::select("SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, MAX(g.score) AS max_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id {$countryWhereClause} {$regionWhereClause} GROUP BY user_id ORDER BY max_score DESC LIMIT 10 {$offset}) t, (SELECT @rownum := {$rowNumInit}) r");
}
我不知道是否可以组合排行榜查询,因为每个查询都返回自己的结果集而不是一行。有 6 个排行榜:(total_score, max_score) x (全球、国家、地区)。每条最多包含 10 条记录:
[
{
"name": "Mina", // Joined from users table.
"user_id": 1,
"toal_score": 7400, // Or max_score for Max Score Leaderboards.
"rank": 1,
},
{...}
]
我认为可以组合所有排名查询,因为它们只返回一行:
// SELECT ... WHERE user_id = 1;
{
"total_score_global": 3540,
"total_score_global_rank": 13,
"total_score_country": 2830,
"total_score_country_rank": 6,
"total_score_region": 2600,
"total_score_region_rank": 2,
"max_score_global": 1084,
"max_score_global_rank": 19,
"max_score_country": 0, // No data for this user with given country.
"max_score_country_rank": 0, // So his rank will be 0.
"max_score_region": 950,
"max_score_region_rank": 1,
}
我的尝试之一:
SELECT
r1.total_score AS total_score_global, r1.rank AS total_score_global_rank,
r2.total_score AS total_score_country, r2.rank AS total_score_country_rank,
r3.total_score AS total_score_region, r3.rank AS total_score_region_rank,
r4.max_score AS max_score_global, r4.rank AS max_score_global_rank,
r5.max_score AS max_score_country, r5.rank AS max_score_country_rank,
r6.max_score AS max_score_region, r6.rank AS max_score_region_rank,
FROM
(SELECT t1.user_id, t1.rank, t1.total_score FROM (SELECT p.user_id, p.total_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, SUM(score) AS total_score FROM game_instances GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.total_score DESC) t1 WHERE t1.user_id = 1) r1,
(SELECT t1.user_id, t1.rank, t1.total_score FROM (SELECT p.user_id, p.total_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, SUM(score) AS total_score FROM game_instances WHERE country = 'cname' GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.total_score DESC) t1 WHERE t1.user_id = 1) r2,
(SELECT t1.user_id, t1.rank, t1.total_score FROM (SELECT p.user_id, p.total_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, SUM(score) AS total_score FROM game_instances WHERE country = 'cname' AND region = 'rname' GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.total_score DESC) t1 WHERE t1.user_id = 1) r3,
(SELECT t1.user_id, t1.rank, t1.max_score FROM (SELECT p.user_id, p.max_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, MAX(score) AS max_score FROM game_instances GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.max_score DESC) t1 WHERE t1.user_id = 1) r4,
(SELECT t1.user_id, t1.rank, t1.max_score FROM (SELECT p.user_id, p.max_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, MAX(score) AS max_score FROM game_instances WHERE country = 'cname' GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.max_score DESC) t1 WHERE t1.user_id = 1) r5,
(SELECT t1.user_id, t1.rank, t1.max_score FROM (SELECT p.user_id, p.max_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, MAX(score) AS max_score FROM game_instances WHERE country = 'cname' AND region = 'rname' GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.max_score DESC) t1 WHERE t1.user_id = 1) r6
我不知道还能如何解释我想要的内容,所以在这里我将列出我编写的所有查询及其结果。
我正在寻找一种更好的方法来获得这些结果,可能是通过减少查询数量。目前,有 12 个查询,太多了。
在所有排名查询中:
SELECT t1.user_id, t1.rank, t1.total_score FROM (SELECT p.user_id, p.total_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, SUM(score) AS total_score FROM game_instances GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.total_score DESC) t1 WHERE t1.user_id = 1;
+---------+------+-------------+
| user_id | rank | total_score |
+---------+------+-------------+
| 1 | 16 | 1090 |
+---------+------+-------------+
SELECT t1.user_id, t1.rank, t1.total_score FROM (SELECT p.user_id, p.total_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, SUM(score) AS total_score FROM game_instances WHERE country = 'Iran, Islamic Republic Of' GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.total_score DESC) t1 WHERE t1.user_id = 1;
+---------+------+-------------+
| user_id | rank | total_score |
+---------+------+-------------+
| 1 | 11 | 1090 |
+---------+------+-------------+
SELECT t1.user_id, t1.rank, t1.total_score FROM (SELECT p.user_id, p.total_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, SUM(score) AS total_score FROM game_instances WHERE country = 'Iran, Islamic Republic Of' AND region = 'Qom' GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.total_score DESC) t1 WHERE t1.user_id = 1;
+---------+------+-------------+
| user_id | rank | total_score |
+---------+------+-------------+
| 1 | 3 | 1090 |
+---------+------+-------------+
SELECT t1.user_id, t1.rank, t1.max_score FROM (SELECT p.user_id, p.max_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, MAX(score) AS max_score FROM game_instances GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.max_score DESC) t1 WHERE t1.user_id = 1;
+---------+------+-----------+
| user_id | rank | max_score |
+---------+------+-----------+
| 1 | 16 | 686 |
+---------+------+-----------+
SELECT t1.user_id, t1.rank, t1.max_score FROM (SELECT p.user_id, p.max_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, MAX(score) AS max_score FROM game_instances WHERE country = 'Iran, Islamic Republic Of' GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.max_score DESC) t1 WHERE t1.user_id = 1;
+---------+------+-----------+
| user_id | rank | max_score |
+---------+------+-----------+
| 1 | 11 | 686 |
+---------+------+-----------+
SELECT t1.user_id, t1.rank, t1.max_score FROM (SELECT p.user_id, p.max_score, @curRank := @curRank + 1 AS rank FROM (SELECT user_id, MAX(score) AS max_score FROM game_instances WHERE country = 'Iran, Islamic Republic Of' AND region = 'Qom' GROUP BY user_id) p, (SELECT @curRank := 0) r ORDER BY p.max_score DESC) t1 WHERE t1.user_id = 1;
+---------+------+-----------+
| user_id | rank | max_score |
+---------+------+-----------+
| 1 | 2 | 686 |
+---------+------+-----------+
在所有排行榜查询中,我们可以更新 OFFSET 和初始 @rownum 值来获取下一页。
SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, SUM(g.score) AS total_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id GROUP BY user_id ORDER BY total_score DESC LIMIT 10 OFFSET 0) t, (SELECT @rownum := 0) r;
+---------+---------+-------------+------+
| name | user_id | total_score | rank |
+---------+---------+-------------+------+
| mina | 17 | 11214 | 1 |
| sar | 19 | 7058 | 2 |
| samaneh | 20 | 5448 | 3 |
| zahraa | 18 | 5390 | 4 |
| reza | 5 | 4402 | 5 |
| kazem | 11 | 4350 | 6 |
| nazanin | 9 | 3428 | 7 |
| saina | 12 | 2724 | 8 |
| sa | 16 | 2568 | 9 |
| zeinab | 14 | 2342 | 10 |
+---------+---------+-------------+------+
SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, SUM(g.score) AS total_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id WHERE g.country = 'Iran, Islamic Republic Of' GROUP BY user_id ORDER BY total_score DESC LIMIT 10 OFFSET 0) t, (SELECT @rownum := 0) r;
+----------+---------+-------------+------+
| name | user_id | total_score | rank |
+----------+---------+-------------+------+
| mina | 17 | 11214 | 1 |
| sar | 19 | 5680 | 2 |
| reza | 5 | 4402 | 3 |
| kazem | 11 | 4350 | 4 |
| saina | 12 | 2724 | 5 |
| sa | 16 | 2568 | 6 |
| hossein | 6 | 1940 | 7 |
| Matrix | 2 | 1670 | 8 |
| Player 3 | 3 | 1568 | 9 |
| zahra | 8 | 1194 | 10 |
+----------+---------+-------------+------+
SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, SUM(g.score) AS total_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id WHERE g.country = 'Iran, Islamic Republic Of' AND g.region = 'Qom' GROUP BY user_id ORDER BY total_score DESC LIMIT 10 OFFSET 0) t, (SELECT @rownum := 0) r;
+---------------------------------+---------+-------------+------+
| name | user_id | total_score | rank |
+---------------------------------+---------+-------------+------+
| sar | 19 | 5680 | 1 |
| Player 3 | 3 | 1568 | 2 |
| MohamadSadegh Gh | 1 | 1090 | 3 |
| Matrix | 2 | 280 | 4 |
+---------------------------------+---------+-------------+------+
SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, MAX(g.score) AS max_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id GROUP BY user_id ORDER BY max_score DESC LIMIT 10 OFFSET 0) t, (SELECT @rownum := 0) r;
+------------+---------+-----------+------+
| name | user_id | max_score | rank |
+------------+---------+-----------+------+
| nazanin | 9 | 3428 | 1 |
| zahraa | 18 | 2666 | 2 |
| sar | 19 | 2650 | 3 |
| mina | 17 | 2380 | 4 |
| zeinab | 14 | 2028 | 5 |
| reza | 5 | 1746 | 6 |
| saina | 12 | 1550 | 7 |
| ali rezvan | 15 | 1514 | 8 |
| sa | 16 | 1480 | 9 |
| samaneh | 20 | 1302 | 10 |
+------------+---------+-----------+------+
SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, MAX(g.score) AS max_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id WHERE g.country = 'Iran, Islamic Republic Of' GROUP BY user_id ORDER BY max_score DESC LIMIT 10 OFFSET 0) t, (SELECT @rownum := 0) r;
+---------+---------+-----------+------+
| name | user_id | max_score | rank |
+---------+---------+-----------+------+
| sar | 19 | 2650 | 1 |
| mina | 17 | 2380 | 2 |
| reza | 5 | 1746 | 3 |
| saina | 12 | 1550 | 4 |
| sa | 16 | 1480 | 5 |
| hossein | 6 | 1288 | 6 |
| zahra | 8 | 1194 | 7 |
| Matrix | 2 | 1162 | 8 |
| kazem | 11 | 1074 | 9 |
| nourf | 7 | 750 | 10 |
+---------+---------+-----------+------+
SELECT t.*, @rownum := @rownum + 1 AS rank FROM (SELECT u.name, g.user_id, MAX(g.score) AS max_score FROM game_instances g INNER JOIN users u ON u.id = g.user_id WHERE g.country = 'Iran, Islamic Republic Of' AND g.region = 'Qom' GROUP BY user_id ORDER BY max_score DESC LIMIT 10 OFFSET 0) t, (SELECT @rownum := 0) r;
+---------------------------------+---------+-----------+------+
| name | user_id | max_score | rank |
+---------------------------------+---------+-----------+------+
| sar | 19 | 2650 | 1 |
| MohamadSadegh Gh | 1 | 686 | 2 |
| Player 3 | 3 | 610 | 3 |
| Matrix | 2 | 280 | 4 |
+---------------------------------+---------+-----------+------+
这不是答案
首先您必须在字段 user_id
上添加索引tmp 样本
SELECT
SUM(sum_table.sum_score) AS total_score_global
, SUM(IF( sum_user.sum_score > sum_table.sum_score, 1,0)) AS total_score_global_rank
, SUM(IF( sum_user.country = sum_table.country AND sum_user.sum_score > sum_table.sum_score, sum_table.sum_score,0)) AS total_score_country
, SUM(IF( sum_user.country = sum_table.country AND sum_user.sum_score > sum_table.sum_score, 1,0)) AS total_score_country
, SUM(IF( sum_user.region = sum_table.region AND sum_user.sum_score > sum_table.sum_score, sum_table.sum_score,0)) AS total_score_region
, SUM(IF( sum_user.region = sum_table.region AND sum_user.sum_score > sum_table.sum_score, 1,0)) AS total_score_region_rank
FROM ( SELECT MAX(score) as sum_score, g.* FROM game_instances AS g GROUP BY user_id ORDER BY sum_score) AS sum_table
JOIN ( SELECT MAX(score) as sum_score, x.* FROM game_instances AS x WHERE user_id = 5 GROUP BY user_id) AS sum_user;
样品
MariaDB [(none)]> use ranking;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [ranking]>
MariaDB [ranking]>
MariaDB [ranking]> SELECT
-> SUM(sum_table.sum_score) AS total_score_global
-> , SUM(IF( sum_user.sum_score > sum_table.sum_score, 1,0)) AS total_score_global_rank
->
-> , SUM(IF( sum_user.country = sum_table.country AND sum_user.sum_score > sum_table.sum_score, sum_table.sum_score,0)) AS total_score_country
-> , SUM(IF( sum_user.country = sum_table.country AND sum_user.sum_score > sum_table.sum_score, 1,0)) AS total_score_country
->
-> , SUM(IF( sum_user.region = sum_table.region AND sum_user.sum_score > sum_table.sum_score, sum_table.sum_score,0)) AS total_score_region
-> , SUM(IF( sum_user.region = sum_table.region AND sum_user.sum_score > sum_table.sum_score, 1,0)) AS total_score_region_rank
->
->
->
-> FROM ( SELECT MAX(score) as sum_score, g.* FROM game_instances AS g GROUP BY user_id ORDER BY sum_score) AS sum_table
-> JOIN ( SELECT MAX(score) as sum_score, x.* FROM game_instances AS x WHERE user_id = 5 GROUP BY user_id) AS sum_user;
+--------------------+-------------------------+---------------------+---------------------+--------------------+-------------------------+
| total_score_global | total_score_global_rank | total_score_country | total_score_country | total_score_region | total_score_region_rank |
+--------------------+-------------------------+---------------------+---------------------+--------------------+-------------------------+
| 33440 | 12 | 9794 | 9 | 2038 | 2 |
+--------------------+-------------------------+---------------------+---------------------+--------------------+-------------------------+
1 row in set (0.00 sec)
MariaDB [ranking]>