1

バックグラウンド ストーリー
毎年恒例のレースのアプリケーション データを格納する MYSQL テーブルがあります。特に、このテーブルには Racer の ID とそのレース アプリケーションの年が保持されます。

今年は、アプリケーションのランダム選択プロセスを重み付けして、X 年連続してアプリケーションを作成した人が選択される可能性が高くなるようにしたいと考えています。

私のPHPスクリプトでは、MYSQLオブジェクトが適用された年ごとに1レコードを返し、ランダムに1つを選択してDB結果配列から割り当てを解除し、それを勝者配列に割り当て、同じIDを持つ他のすべての勝者を無視します今年のために。

実際の問題
この方法の問題は、現在の MYSQL クエリが、今年および過去のレースに応募したすべての人のすべてのレコードを返すことです。2014年以前の継続的なアプリケーションのみを返す方法はありますか(できればMYSQLを使用して)?

このSQL FIddleからの結果セットの例は、"1, 1, 1, 2, 2, 2, 2, 3" になります。

私の現在のクエリは次のとおりです。

SELECT a.racer_id FROM applications a

WHERE a.racer_id IN
    (
        SELECT ab.racer_id FROM applications ab

        WHERE ab.racer_id = a.racer_id AND ab.race_year=2014
    )

ORDER BY RAND();

2014 年以前の継続的な記録だけでなく、過去のすべての年を取得するため、これは機能しません。

4

1 に答える 1

0

この質問のもう 1 つの言い方は、レーサーが競技しなかった直近の年を見つけることです。次に、現在の年からその年を引いたものが、連続する年数になります。

年とレーサーの間でクロス結合を行い、アプリケーションに左結合することで、最新の年を取得できます。試合がないのは、そのレーサーが出場しなかった年です。

すべての年に出場したレーサーを処理するには、追加の簿記を行う必要があります。最後のクエリは次のとおりです。

select racers.racer_id,
       maxyear - max(case when a.race_year is null then years.race_year
                          else const.minyear - 1
                     end)
from (select distinct race_year
      from applications
     ) years cross join
     (select distinct racer_id
      from applications
     ) racers cross join
     (select max(race_year) as maxyear, min(race_year) as minyear
      from applications
     ) const left outer join 
     applications a
     on a.race_year = years.race_year and
        a.racer_id = racers.racer_id
group by racers.racer_id;

これが SQL Fiddle のデータとどのように関連しているかはわかりません。そこには 4 人のレーサーがいますが、質問には 8 つの推奨値があります。

編集:

今、私はそれを取得します。それはかなり合理的です。次のクエリは、基本的に上記の考え方を拡張してapplication、アプリケーションなしで最大年より後の任意の年を取得するために に戻します。サブクエリは上記を簡略化したものです。

select a.racer_id
from (select racers.racer_id,
             max(case when a.race_year is null then years.race_year
                 end) as maxyear
      from (select distinct race_year
            from applications
           ) years cross join
           (select distinct racer_id
            from applications
           ) racers left outer join 
           applications a
           on a.race_year = years.race_year and
              a.racer_id = racers.racer_id
      group by racers.racer_id
     ) ry join
     applications a
     on a.racer_id = ry.racer_id and
        (a.race_year > ry.maxyear or ry.maxyear is null);
于 2013-08-07T22:19:21.037 に答える