mySQL - 连胜

时间:2012-04-19 08:58:26

标签: mysql

您好我想找到一种方法,为我桌上的每个成员找到最大的连胜纪录。当桌子建成时,这从未在计划中发生过,所以我寻求帮助以实现这一目标。

我的结构如下:

id  player_id   opponant_id     won     loss    timestamp 

如果是人游戏,则玩家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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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集。该代码将根据您要使用的语言而有所不同,但逻辑上这些是两种选择。