2

为了在我的游戏服务器上实现排名系统,我将每个玩家的一些信息存储在 MySQL 数据库中。我有以下数据库表。

players带有示例数据的表格:

id | steamId | deaths
---+---------+-------
1  | asdja   | 2
2  | kfjsl   | 5

weapons带有示例数据的表格:

playerId | weaponId | kills
---------+----------+------
1        | 5        | 8
1        | 9        | 7
2        | 3        | 3
2        | 6        | 10
2        | 7        | 2

您会看到我没有将每个玩家的击杀数存储在players-table 中,因为我可以简单地从weapons-table 计算它。我对 SQL 查询不是很熟悉,但我完成了创建以下查询以选择具有以下字段的简单数据集:

kills,
deaths,
kill-death-rate (kdrate),
count (maximum number of players),
rank (current ranking position, sorted by kills)

查询:

SELECT
    SUM(weapons.kills) AS `kills`,
    `deaths`,
    (SUM(kills) / IF(deaths, deaths, 1)) AS `kdrate`,
    (SELECT COUNT(*) FROM `players`) AS `count`,
    (
        SELECT
            COUNT(*)
        FROM
            (
                SELECT
                    p.id AS id2,
                    SUM(w.kills) AS kills2,
                    p.deaths AS deaths2,
                    p.steamId AS steamId2
                FROM
                    weapons AS w,
                    players AS p
                WHERE
                    p.id = w.playerId
                GROUP BY
                    p.id
            ) AS temp
        WHERE
            temp.kills2 >= (
                SELECT
                    SUM(weapons.kills) AS `kills`
                FROM
                    `players`,
                    `weapons`
                WHERE
                    players.id = weapons.playerId AND
                    `id` = 1
                GROUP BY
                  `id`
            )
        ORDER BY
            temp.kills2 DESC,
            temp.deaths2 ASC,
            temp.steamId2 ASC
    ) AS `rank`
FROM
    `players`
INNER JOIN
    `weapons`
ON
    players.id = weapons.playerId
WHERE
    `id` = 1
GROUP BY
    `id`

有两个问题:

1.) 查询很糟糕。

2.) 使用给定的示例数据执行此查询会导致“相同排名”。我的意思是,两个玩家的排名相同,因为我的两个玩家的击杀数量相同。但是相反,玩家 1 应该排在 1 位,因为他的死亡人数比玩家 2 少。我不知道我怎么能意识到这一点。

提前致谢!

编辑:@Manueru_mx 给了我一个基本的想法:根据他的回答,我得到了以下代码:

SELECT
    id,
    kills,
    deaths,
    kdrate,
    COUNT(*) AS rank,
    (SELECT COUNT(*) FROM players) AS `count`
FROM
    (
        SELECT
            pys.id AS id,
            SUM(wps.kills) AS kills,
            pys.deaths AS deaths,
            (SUM(wps.kills) / pys.deaths) as kdrate
        FROM
            players pys
        INNER JOIN
            weapons wps
        ON
            pys.id = wps.playerid
        GROUP BY
            pys.id
        ORDER BY
            2 DESC,
            3,
            4 ASC
    ) AS tmp
WHERE
    id = 1

剩下的唯一问题是,rank在这两种情况下都是 1。

4

3 回答 3

2

这是我的“解决方案”。这个查询更简单,但得到你正在寻找的结果

select 
pys.steamID, SUM(wps.kills) as Kills,
SUM(pys.deaths) as Deaths,
(sum(wps.kills)/sum(pys.deaths)) as kdratio
--,COUNT(pys.steamID) as PlayersC
from players pys
inner join  weapons wps on pys.id = wps.playerid
group by pys.steamID
order by 2 DESC, 3, 4 ASC

添加排名。

SELECT
    id,
    kills,
    deaths,
    kdrate,
    ranking_usr as rank,
    (SELECT COUNT(*) FROM players) AS `count`
FROM
    (
        SELECT
            @row := @row + 1 AS ranking_usr
            pys.id AS id,
            SUM(wps.kills) AS kills,
            pys.deaths AS deaths,
            (SUM(wps.kills) / pys.deaths) as kdrate
        FROM
            players pys
        INNER JOIN
            weapons wps
        ON
            pys.id = wps.playerid
        GROUP BY
            pys.id
        ORDER BY
            2 DESC,
            3,
            4 ASC
    ) AS tmp
WHERE
    id = 1
于 2012-10-19T14:38:14.320 回答
2

基于 Manueru_mx 答案,这里是解决方案:

SELECT
    *
FROM
    (
    SELECT
        id,
        kills,
        deaths,
        kdrate,
        @rownum := @rownum + 1 AS rank,
        (SELECT COUNT(*) FROM players) AS `count`
    FROM
        (
            SELECT
                pys.id AS id,
                SUM(wps.kills) AS kills,
                pys.deaths AS deaths,
                (SUM(wps.kills) / pys.deaths) as kdrate
            FROM
                players pys
            INNER JOIN
                weapons wps
            ON
                pys.id = wps.playerid
            GROUP BY
                pys.id
            ORDER BY
                2 DESC,
                3,
                4 ASC
        ) AS tmp,
        (SELECT @rownum:= 0) r
    ) AS tmp2
WHERE
    id = 1
于 2012-10-19T15:19:31.293 回答
0

你期待的结果是什么?您可以通过运行简单地知道玩家完成了多少杀戮:

select id, (select sum (kills) from weapons where playerid = p.id)
from  players p
于 2012-10-19T14:24:02.963 回答