2

ゲームの結果を受け取るテーブルが 1 つあります。各ゲームには独自の ID があり、7 日間のみ有効です。1 日 1 回、すべてのゲームの結果がこのテーブルに入れられます (スキル A、スキル B、... の結果はそれぞれ列に格納されます)。

MySQL で取得できるようにするために必要なもの: 各ゲーム (game_id) とそのすべての結果、および各日の結果間の進行状況 (上下した可能性があります) を表示する必要があります。

次のような結果になるはずです。

Game_id    date        result_a    progress    result_b    progress      
1234       2013-09-01  10          0           8           0
1234       2013-09-02  08          -2          6           -2
1234       2013-09-03  15          7           10          4
1234       2013-09-04  19          4           13          3
4321       2013-09-01  09          0           7           0
4321       2013-09-02  18          9           9           2
4321       2013-09-03  15          -3          11          2
4321       2013-09-04  09          -6          16          4

これを簡単に処理するためのヒントはありますか(約4000行になる可能性があります...)?

http://sqlfiddle.com/#!2/70a96/4

4

3 に答える 3

1

次のクエリは、必要な出力になります (列の順序を除く)。ここでのトリックは、前のゲーム ID がまだ同じ (変数) かどうかをチェックすることです。そうであれば、前の結果データ (変数) を減算して結果を取得するか、0 を返すだけです。

列の順序が少し異なるのはなぜですか? これは、そうしないと、変数が現在の値で既にオーバーライドされているため、結果として常に 0 になるためです。そのため、比較と減算の後に「前の」変数を設定する必要があります。

SELECT
    @progress_a := IF(@prevGameId = data.game_id,
                      data.result_a - @prevResultA,
                      0) AS 'progress_a',
    @prevResultA := data.result_a AS 'result_a',
    @progress_b := IF(@prevGameId = data.game_id,
                      data.result_b - @prevResultB,
                      0) AS 'progress_b',
    @prevResultB := data.result_b AS 'result_b',
    data.registration_date,
    (@prevGameId := data.game_id) AS 'game_id'
FROM (SELECT
          game_id,
          result_a,
          result_b,
          registration_date
      FROM games
      ORDER BY game_id, registration_date
     ) AS data
JOIN (SELECT
          @prevGameId := NULL,
          @prevResultA := NULL,
          @prevResultB := NULL
     ) dummy

最後の JOIN は、変数を初期化するために必要です (1 つのクエリしか実行できない場合)。それ以外の場合は、SET ステートメントを使用して (SELECT の前に) 変数を初期化できます。

各ゲームのレコードがグループ化されるとは限らないため、FROM 内の SELECT が必要です。そのため、それらが一緒に注文され、登録日にソートされるようにしています。利点は、各登録日 (ゲームごと) が一意であることを保証できない場合、各ゲーム/registration_date をグループ化できることです。

注: 重大なパフォーマンスの問題が発生した場合 (そうではないはずです)、実際にアプリケーションで処理するか、データを挿入するときに進行状況を計算する必要があります (「進行状況」データを冗長に保存します)。

于 2013-09-28T23:22:09.873 に答える