2016-08-21 7 views
1

私のゲームのウェブサイトを整理しようとしています スコアはSQLに格納されています。 ゲームにはすべてのイベントの得点が格納されているので、当然のことながら各プレイヤーには倍数があります。 各プレーヤーのトップを集めようとしています。現時点で は、私はこれが正常に動作し、グループ化SQLのグループ化とテーブルの値

SELECT TOP(250) * FROM 
(SELECT  CharName, CharType, MAX(Point) AS SCORE 
FROM   SOD2RecBySandurr 
GROUP BY CharName, CharType) AS derivedtbl_1 WHERE CharName NOT 
LIKE '\[GM\]%' ESCAPE '\' AND SCORE NOT LIKE '0' ORDER BY SCORE DESC 

を使用しています、しかし、私は、ウェブサイトに表示していた情報にキル数を追加したいです。 私はグループごとにKillCountを追加しようとしましたが、すべてのスコアを自然に表示します。

SELECT TOP(250) * FROM 
(SELECT  CharName, CharType, KillCount, MAX(Point) AS SCORE 
FROM   SOD2RecBySandurr 
GROUP BY CharName, CharType, KillCount) AS derivedtbl_1 WHERE CharName NOT 
LIKE '\[GM\]%' ESCAPE '\' AND SCORE NOT LIKE '0' ORDER BY SCORE DESC 

は、私はそれが文字がcharnameに基づいてグループ化を行うが、私はそれからではなく、グループ内の選択にkillcountしている場合、それが戻ってエラーをスロー chartypeとkillcountを表示する方法を作ることができます。

これは私が困惑しています:/名前に基づいてそれらをグループ化していない理由を理解していますが(killcountは他のエントリにマッチしません)、私はちょうどそれがグループselect関数です。

EDIT:

今回の結果は次のとおりです。

私は最高のスコアでソートしたいが、そのためのキル数を含める

Player A - Score 1 - Kills 1 (Be that the max score) 
Player B - Score 1 - Kills 1 

スコア見たい
Player A - SCORE 1 - Kills 1 
Player A - SCORE 2 - Kills 2 
Player A - SCORE 3 - Kills 3 
Player B - SCORE 1 - Kills 1 

+0

使用できるコマンドのタイプはありますか?私は1つを見つけることができたhaventは:/ –

+0

はあなたが現在の結果を表示することができ、その結果を期待し、また、あなたが – TheGameiswar

+0

SQLEXPRESS 2008R2 現在の結果(あらゆる試みのように)各選手のスコアを与えるので Playerを使用しているSQL Serverのバージョンを追加します - ScoreA - キルCOUNTA プレイヤーA - 私はあなたが現在の結果との質問を更新してくださいすることができ、各プレイヤー –

答えて

1

私がこれを読んでいる方法から、最高の250人のプレイヤーがポイントで殺到し、トップキル試合で?

まず、OFFSET/FETCHを使用して、使用するリソースを制限し、クライアントがクエリのページ区切りを指示できるようにします。いくつかの制限がありますが、MSDNのORDER BY CLAUSEを読んで自分で決定してください。

  • KILLCOUNTとPOINTはあなたが得点王を返すようにしたいので、また最大の範囲で殺し続ける両方の列

MAXを使用することを検討して、同じになることはありません。あなたのセッションスコープ(地図?シリーズ?オールタイム?)によっては、SUMおよび/またはOVER PARTITION BY句を使用する必要があるかもしれません(OVER句を直接OFFSET/FETCHではサポートされていません)

あなたがグループ化されている方法を考えますそれらとグループに含まれていないデータはすべて破棄されます。したがって、これらの列には、あらゆる用途に使用するための集約関数が必要です(ほとんどの場合)。

あなただけのトップ250得点とそのトップキルを望むた場合は、一つの解決策は、以下のことがあります

SELECT * 
FROM (SELECT  CharName, CharType, MAX(KillCount) AS KillCount, MAX(Point) AS SCORE 
       FROM   SOD2RecB 
       WHERE CharName NOT LIKE '\[GM\]%' ESCAPE '\' 
       -- AND Point NOT LIKE '0' 
       GROUP BY CharName, CharType 
       HAVING MAX(Point) > 0) as SRC 
ORDER BY SCORE DESC 
FETCH FIRST 250 ROWS ONLY 

WHEREHAVINGSARG引数を取ります。 SQL Serverは、要因に応じて行ではなく高速なフィルタリンググループを実行する可能性があります。ただし、とにかくWHERE句を使用することを検討してください。

UPDATED(コメント欄を参照)私がこれを書いたとき、私は非常に疲れていたので、間違いがあるかもしれません。

ただし、MAX(ポイント)に関連するKillCount列が返されるようにする場合は、上記のクエリでは、指定したとおりにこの結果が保証されるわけではありません。

グループbyは、GROUP BYにない列の関係を削除します。この件については、SOにいくつかの投稿がありますが、詳細については説明しますが、基本的にサブクエリを使用して、SQL Serverが返された結果を適切にフィルタリングできるようにする必要があります。

パフォーマンス上の理由から、アルゴリズムを単純化する方法がありますが、テーブルスキャンが使用されることに注意してください。テーブル・スキャンは必ずしも悪いわけではありませんが、各行で完全で最適化されていない問合せを実行すると問題が生じるため、問合せへの影響を考慮してください。

CTEではなく大きなデータセットで高速になることがありますが、使用されるメソッドが必要最小限の比較を使用することを確認してください(ブール値は文字列データ型の暗黙の変換よりもはるかに速い数値です)。できるだけSARGable。

この例では、方法の例としてOUTER APPLYの代わりにINNER JOINを使用することを選択しました。主なアイデアは、グループ(CharName + CharType)の1つの値(ポイント)とセットに戻される最大値を比較することでした。間違いなく比較の基数を考慮する。

SELECT SRC.CharName 
    , SRC.CharType 
    , SRC.KillCount 
    , TGT.SCORE 
FROM SOD2RecB AS SRC 
INNER JOIN (SELECT CharName, CharType, MAX(Point) AS SCORE 
      FROM   SOD2RecB 
      WHERE CharName NOT LIKE '\[GM\]%' ESCAPE '\' 
       AND Point NOT LIKE '0' 
      GROUP BY CharName, CharType) as TGT ON CharName = TGT.CharName 
               , CharType = TGT.CharType 
               , Point = TGT.Score 
-- WHERE SRC.Point = TGT.Score 
ORDER BY TGT.SCORE DESC 
FETCH FIRST 250 ROWS ONLY 
+0

すごい迫力、私の携帯電話があやふやだった...本解決策 - ScoreB有効じゃない。ハングアップ –

+0

明確にするために、キル数はスコアにリンクされていますが、最高のキル数は必ずしも最高のスコアとは限りません。 そのプレイヤーの最高得点に関連するキル数を表示したいが、私は各プレイヤーの得点を表示したい(0点を除いて) –

+0

それはうまくいきました。ありがとう、 確認するには、正しい正義? (スコア/キル数が最初にキル数に一致するスコアのように)? –