3

嗨,我正在尝试找出一种方法来为我桌上的每个成员找到最大的连胜纪录。当桌子建成时,这从未在计划中发生,所以我寻求帮助以了解如何实现这一目标。

我的结构如下:

id  player_id   opponant_id     won     loss    timestamp 

如果是个人游戏,玩家 id 就是他们的 id。如果他们被某人挑战,他们的 id 是对手的 id,而获胜的损失(1 或 0)与 player_id 相关。

我想为每个用户找到最大的连胜纪录。

任何人都对如何使用当前表结构执行此操作有任何想法。

问候

编辑

这是一些测试数据,其中 id 3 是有问题的玩家:

id  player_id   won     loss    timestamp
1   6           0       1       2012-03-14 13:31:00
13  3           0       1       2012-03-15 13:10:40
17  3           0       1       2012-03-15 13:29:56
19  4           0       1       2012-03-15 13:37:36
51  3           1       0       2012-03-16 13:20:05
53  6           0       1       2012-03-16 13:32:38
81  3           0       1       2012-03-21 13:14:49
89  4           1       0       2012-03-21 14:01:28
91  5           0       1       2012-03-22 13:14:20
4

2 回答 2

4

试试这个。 编辑考虑损失行

SELECT 
    d.player_id,
    MAX(d.winStreak) AS maxWinStreak
FROM (
    SELECT
        @cUser := 0,
        @winStreak := 0
) v, (

    SELECT
        player_id,
        won,
        timestamp,
        @winStreak := IF(won=1,IF(@cUser=player_id,@winStreak+1,1),0) AS winStreak,
        @cUser := player_id
    FROM (
        (
            -- Get results where player == player_id
            SELECT
                player_id,
                won,
                timestamp
            FROM matchTable
        ) UNION (
            -- Get results where player == opponent_id (loss=1 is good)
            SELECT
                opponent_id,
                loss,
                timestamp
            FROM matchtable
        )
    ) m
    ORDER BY 
        player_id ASC,
        timestamp ASC
) d
GROUP BY d.player_id

这通过选择所有赢/输并计算连续获胜来实现。然后子查询按 player_id 分组,并且在循环通过时计算的最大 winStreak 是每个玩家的输出。

无论如何,它似乎对我的测试数据集很有效:)

为了更有效地做到这一点,我会重组,即

matches (
    matchID,
    winningPlayerID,
    timeStamp
)

players (
    playerID
    -- player name etc
)

matchesHasPlayers (
    matchID,
    playerID
)

这将导致内部查询

SELECT
    matches.matchID,
    matchesHasPlayers.playerID,
    IF(matches.winningPlayerID=matchesHasPlayers.playerID,1,0) AS won
    matches.timestamp
FROM matches
INNER JOIN matchesHasPlayers
ORDER BY matches.timestamp

导致

SELECT 
    d.player_id,
    MAX(d.winStreak) AS maxWinStreak
FROM (
    SELECT
        @cUser := 0,
        @winStreak := 0
) v, (
    SELECT
        matchesHasPlayers.playerID,
        matches.timestamp,
        @winStreak := IF(matches.winningPlayerID=matchesHasPlayers.playerID,IF(@cUser=matchesHasPlayers.playerID,@winStreak+1,1),0) AS winStreak,
        @cUser := matchesHasPlayers.playerID
    FROM matches
    INNER JOIN matchesHasPlayers
    ORDER BY 
        matchesHasPlayers.playerID ASC,
        matches.timestamp ASC
) d
GROUP BY d.player_id
于 2012-04-19T09:24:08.627 回答
0
SELECT * FROM
(
    SELECT player_id, won, loss, timestamp
    FROM games
    WHERE player_id = 123
    UNION
    SELECT opponant_id as player_id, loss as won, won as loss, timestamp
    FROM games
    WHERE opponant_id = 123
)
ORDER BY timestamp

这将为您提供按时间戳排序的一名玩家的所有结果。然后您需要循环这些结果并计算获胜记录,或者将它们全部连接成一个字符串,然后使用字符串函数在该字符串中找到您的最高 11111 集。该代码将根据您要使用的语言而有所不同,但从逻辑上讲,这是两种选择。

于 2012-04-19T09:12:03.337 回答