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

これにより、タイムスタンプ順に並べられた 1 人のプレーヤーのすべての結果が得られます。次に、それらの結果をループして勝利記録をカウントするか、それらすべてを文字列に連結してから、文字列関数を使用してその文字列で最高の 11111 セットを見つける必要があります。そのコードは、使用する言語によって異なりますが、論理的にはこれら 2 つの選択肢があります。

于 2012-04-19T09:12:03.337 に答える