-3

次のようなテーブルがあります。

| ID | game | player | their_turn |
===================================
| 1  | 1    | 1      | 0          |
-----------------------------------
| 2  | 1    | 2      | 1          |
-----------------------------------
| 3  | 1    | 3      | 0          |
-----------------------------------
| 4  | 1    | 4      | 0          |
-----------------------------------
| 5  | 1    | 5      | 0          |

私の目標は、ID で並べ替えられた特定のゲームについて、your_turn が 1 の直後のプレーヤーを選択し、最大 ID に達したときに最小/最初の ID にループバックすることです。

例:今のようにプレイヤー2のターンならプレイヤー3を選択したい、プレイヤー5のターンならプレイヤー1を選択したい、そしてプレイヤー1の時はプレイヤー2を選択したい.

すべての行を選択した後、いつでも PHP でこれを処理できますが、MySQL でこれを正しく行うにはどうすればよいか疑問に思っていました。

更新: 新しいテーブル構造

テーブルを再構築することになりました。their_turn は別のテーブルに移動されました (無関係な列は除外されます):

Players          Rounds
| ID | game |    | ID | game | player |
=============    ======================
| 1  | 1    |    | 1  | 1    | 1      |
| 2  | 1    |    | 2  | 1    | 2      |
| 3  | 1    |
| 4  | 1    |
| 5  | 1    |

つまり、同じ目標です。並んでいる次のプレーヤーを選択します。ID がゲームの最新ラウンドのプレイヤー ID より大きいか、そうでない場合は、そのゲームの最小プレイヤー ID のいずれかです。私は、MySQL で IF ステートメントを使用したことがありません。これは必要なことだと思いますが、その方法を理解するのに苦労しています。

4

2 に答える 2

2

UPDATEこれは、変更されたテーブル スキーマのクエリです。

SELECT CASE WHEN player + 1 > max_id 
            THEN min_id
            ELSE player + 1
       END next_player
  FROM
(
  SELECT MAX(id) max_id, MIN(id) min_id
    FROM players
   WHERE game = 1
) p CROSS JOIN
(
  SELECT player 
    FROM rounds
   WHERE game = 1
   ORDER BY id DESC
  LIMIT 1
) r

出力:

| | NEXT_PLAYER |
---------------
| | 3 |

これがSQLFiddleのデモです

余談ですが 、質問の変更はやめてください。テーブル スキーマを変更した場合、またはその他の大幅な変更を行った場合は、元の質問に対する回答を評価して高く評価し、新しい質問を投稿してください。

元の質問への回答: ID が連続していることが保証されていない場合の解決策

(
  SELECT *
    FROM Table1
   WHERE game = 1
   ORDER BY id
   LIMIT 1
)
 UNION ALL
(
  SELECT *
    FROM Table1
   WHERE game = 1
     AND ID > 
   (
     SELECT MIN(id) 
       FROM Table1 
      WHERE game = 1 
        AND their_turn = 1
   )
   ORDER BY id
   LIMIT 1
)
 ORDER BY id DESC 
 LIMIT 1

ゲームのIDが常に連続している場合は、次のことができます

SELECT t.*
  FROM Table1 t 
 WHERE id = 
(
  SELECT CASE WHEN MAX(id * their_turn) + 1 > MAX(id) 
              THEN MIN(id) 
              ELSE MAX(id * their_turn) + 1 END next_id
    FROM Table1
   WHERE game = 1
)

サンプルデータに基づく両方のケースの出力は次のとおりです。

| | ID | ゲーム | ゲーム | プレイヤー | THEIR_TURN |
-----------------------------------
| | 3 | 1 | 3 | 0 |

両方のクエリのSQLFiddleデモを次に示します。

于 2013-08-03T03:40:16.750 に答える
0

一般的なアルゴリズム:

  • their_turn=1 のプレイヤーの位置を見つけます (ヒント: 実際の位置を決定するには、ランクを作成する必要があります)。
  • ステップ 1 からポジションを選択 + 1 モジュロ プレーヤーの合計数
于 2013-08-03T03:37:29.733 に答える