2017-03-12 9 views
0

私はオンラインシューティングゲームのゲーム統計を追跡するサービスを作成しています。クライアントはイベントをサーバーに報告し、SQL Serverデータベースに記録します。サーバーは、クライアントレポートから集計されたゲームイベントのレポートを生成することが期待されています。イベントクレームの真正性は、レポートしたクライアントの数に基づいています。LinqからSQLへのサブクエリから重複行セットを除外する

私は、発生した時間(7秒以内)に基づいて異なるクライアントからのイベントレポートをグループ化するLinq-to-SQLクエリを持っています。

Events 
    .Select(e => 
     Events.Where(ev => 
      // Same event type 
      ev.Discriminator == e.Discriminator && 
      // Same match 
      ev.ServerIpAddress == e.ServerIpAddress && 
      SqlMethods.DateDiffSecond(ev.MatchStartTime, e.MatchStartTime) < 30 && 
      // Find nearby events 
      Math.Abs(ev.MatchTime.TotalSeconds - e.MatchTime.TotalSeconds) < 7 && 
      // That are duplicate 
      ev.VictimTribesGuid == e.VictimTribesGuid && 
      ev.KillerTribesGuid == e.KillerTribesGuid && 
      ev.KillType == e.KillType && 
      ev.Weapon == e.Weapon 
     ) 
    ) 

これは、以下を返す:

Result

イベントは(最初の2行を参照)予想されるようにグループ化されたが、外側のクエリが「当たりイベント」であるように、グループが複製されています。

これらの重複グループを削除する方法はありますか?

+0

まず、すべてのイベントが自分自身を選択します。しかし、「Math.Abs​​」のために、マッチAがマッチBの7秒以内であれば、AとBの両方にAとBが含まれます。 –

+0

はい - 余分な「A + B」の結果(およびA + B + C + ...より多くの行の場合) –

+0

'Math.Abs​​'を削除して(そして0〜7秒の間で指定すると)、近くの複数の対応するイベント私はまた、 '孤独な'イベントをクエリに含めたいと思っています。 –

答えて

0

.Distinct();を使用してください。

Events 
    .Select(e => 
     Events.Where(ev => 
      // Same event type 
      ev.Discriminator == e.Discriminator && 
      // Same match 
      ev.ServerIpAddress == e.ServerIpAddress && 
      SqlMethods.DateDiffSecond(ev.MatchStartTime, e.MatchStartTime) < 30 && 
      // Find nearby events 
      Math.Abs(ev.MatchTime.TotalSeconds - e.MatchTime.TotalSeconds) < 7 && 
      // That are duplicate 
      ev.VictimTribesGuid == e.VictimTribesGuid && 
      ev.KillerTribesGuid == e.KillerTribesGuid && 
      ev.KillType == e.KillType && 
      ev.Weapon == e.Weapon 
     ).Distinct(); 
    ) 
+0

残念ながら、これは同じ結果をもたらします。( –

+0

Linqで実行する前に、データベースでこれを実行できればもっと良いと思います。 –

1

GroupByここでは適切な方法であるようです。しかし、これは見た目ほど簡単ではありません。それは合理的な操作であると思われます。多かれ少なかれ同一のイベントをグループ化できるように、何らかの「同等性」を定義する必要がありますか?同じゲーム内で平等を選択すると、は7秒未満です。

しかし、私がhereと記述したのと同様の問題があります。 3つのイベントab、及びcは0、5S及び10Sに発生した場合、 "7Sルール" は、以下の "等式" を定義:

a ≈ b 
b ≈ c 

しかしabは離れ10Sあるので

a !≈ c 

数学用語では、これは等価性が推移的でないことを意味します。つまり、イベントが7秒未満であるという事実だけでイベントをグループ化することはできません。

私はあなたには異なるアプローチが必要だと思います。ゲームで最初に発生するイベントのカウントダウンを開始する必要があります。このイベントの後7秒以内に発生した(同じゲーム内の)すべてのイベントをカウントする必要があります。その後7秒を超えて開始した最初のイベントは、新しいカウントを開始します。これは単純なforeachで行うことができます。

上記のすべてが、ゲームが「平等」であると判断する条件であるMatchStartTimeにも当てはまります。私はあなたがゲームインスタンスにGUIDを割り当てるなど、その事実を確立するあまりあいまいではない方法を見つけることを試みるべきだと思います。それ以外の場合は、イベント「平等」と同じアプローチを取る必要があります。

関連する問題