如何结合我的总排名和排行榜查询?

问题描述 投票:0回答:2

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
php mysql sql laravel rank
2个回答
0
投票

我不知道还能如何解释我想要的内容,所以在这里我将列出我编写的所有查询及其结果。

我正在寻找一种更好的方法来获得这些结果,可能是通过减少查询数量。目前,有 12 个查询,太多了。

  1. 总分全球排名

在所有排名查询中:

  • 如果给定用户没有记录,则返回总分/最大分:0 和排名:0。
  • 全球、国家和地区分数可能会有所不同,因为用户可能稍后设置或更改其国家和地区。
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 |
+---------+------+-------------+
  1. 总分国家排名:
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 |
+---------+------+-------------+
  1. 总分地区排名:
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 |
+---------+------+-------------+
  1. 最高分全球排名:
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 |
+---------+------+-----------+
  1. 最高得分国家排名:
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 |
+---------+------+-----------+
  1. 最高分地区排名:
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 |
+---------+------+-----------+
  1. 总分全球排行榜:

在所有排行榜查询中,我们可以更新 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 |
+---------+---------+-------------+------+
  1. 总分国家排行榜:
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 |
+----------+---------+-------------+------+
  1. 总分地区排行榜:
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 |
+---------------------------------+---------+-------------+------+
  1. 最高分全球排行榜:
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 |
+------------+---------+-----------+------+
  1. 最高分数国家排行榜:
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 |
+---------+---------+-----------+------+
  1. 最高分地区排行榜:
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 |
+---------------------------------+---------+-----------+------+

0
投票

这不是答案

首先您必须在字段 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]>
© www.soinside.com 2019 - 2024. All rights reserved.