计算赢率

时间:2017-11-29 06:33:39

标签: sql postgresql

我必须从表格(bots_match_history)计算玩家的赢率,其中包含以下格式的数据:

id  |    username     | sub_level_id | bot_type | match_result | system_win_balance |         created_at         | analyzed | stakes 
------+-----------------+--------------+----------+--------------+--------------------+----------------------------+----------+--------
 5487 | ashishish       |            5 | hard     | l            |               -831 | 2017-11-29 06:26:13.288267 | f        |     18
 5486 | dilip.kumar     |            3 | hard     | l            |               -821 | 2017-11-29 06:25:09.106075 | f        |     50
 5485 | abhinav.garg    |            5 | hard     | w            |               -791 | 2017-11-29 06:24:07.589281 | f        |     18

我只需要使用那些尚未被分析过的条目(已分析=假),并且特定级别的条目超过3个。

这是我写过的查询,不知何故,对于某些条目,它返回的赢率为> 100%。

WITH total AS (
    SELECT COUNT(b.match_result) AS total_matches, b.bot_type, sl.level_id, b.stakes
    FROM bots_match_history b
    JOIN sub_levels sl ON b.sub_level_id = sl.id
    WHERE b.analyzed=FALSE 
    GROUP BY b.bot_type, sl.level_id, b.stakes
    HAVING COUNT(b.match_result) >=3
)
SELECT total.bot_type, total.level_id, total.stakes, round(cast(((
        SELECT COUNT(b2.*)
        FROM bots_match_history b2
          JOIN sub_levels sl2 ON b2.sub_level_id = sl2.id
        WHERE b2.match_result='w' AND b2.analyzed=FALSE
            AND b2.bot_type = total.bot_type AND sl2.level_id = total.level_id
    )::FLOAT * 100.0 / total.total_matches) AS NUMERIC), 2)::FLOAT AS win_percentage
FROM total, bots_match_history b3
JOIN sub_levels sl3 ON sl3.id = b3.sub_level_id
WHERE b3.bot_type = total.bot_type AND sl3.level_id=total.level_id
GROUP BY total.bot_type, total.level_id, total.stakes, total.total_matches;

此查询有什么错误,它返回的胜率超过100%?

1 个答案:

答案 0 :(得分:1)

您要按stakes对总计进行分组,但之后不要加入,因此总计(限于某些赌注)中的一行可以与计算总数相比更多行(取决于多少行数)那些都赢了)。

我做了小提琴,不包括sub_levels表,而是用sub_level_id替换它来代替分组和加入:http://dbfiddle.uk/?rdbms=postgres_9.6&fiddle=b3558b9d3cddc63a47d3f29a4a6c08f6

修复的SQL应如下所示:

WITH total AS (
    SELECT COUNT(b.match_result) AS total_matches, b.bot_type, sl.level_id, b.stakes
    FROM bots_match_history b
    JOIN sub_levels sl ON b.sub_level_id = sl.id
    WHERE b.analyzed=FALSE 
    GROUP BY b.bot_type, sl.level_id, b.stakes
    HAVING COUNT(b.match_result) >=3
)
SELECT total.bot_type, total.level_id, total.stakes, round(cast(((
        SELECT COUNT(b2.*)
        FROM bots_match_history b2
          JOIN sub_levels sl2 ON b2.sub_level_id = sl2.id
        WHERE b2.match_result='w' AND b2.analyzed=FALSE
            AND b2.bot_type = total.bot_type AND sl2.level_id = total.level_id
            AND b2.stakes = total.stakes
    )::FLOAT * 100.0 / total.total_matches) AS NUMERIC), 2)::FLOAT AS win_percentage
FROM total, bots_match_history b3
JOIN sub_levels sl3 ON sl3.id = b3.sub_level_id
WHERE b3.bot_type = total.bot_type AND sl3.level_id=total.level_id
  AND b3.stakes=total.stakes
GROUP BY total.bot_type, total.level_id, total.stakes, total.total_matches;

此外,如果您仅限于分析的行,则可能会得到(IMO)不正确的结果。我看到一组参数的40%winrate,然后检查实际的行,实际上有3个赢和3个输掉的游戏让我困惑了一段时间才注意到其中一个赢得的游戏是"分析"已经