2012-02-17 5 views
2

私はGamersというテーブルを持っています。 ゲーマーは、列GamerID,GameID,Scoreを含みます。mysqlは単一のテーブルで各カテゴリのベストを選択します

私は各ゲームの最高得点の選手を選ぶことに興味があります。例えば

、クエリ後

|Gamers 
|------------------------- 
|GamerID | GameID | Score 
|1  | 1  | 10 
|2  | 1  | 10 
|3  | 1  | 10 
|4  | 1  | 90 
|5  | 2  | 40 
|6  | 2  | 10 
|7  | 3  | 10 
|8  | 3  | 30 

は、私はこれを行うだろうクエリで何GamerID 4、5と8の行を得ることを期待?

+0

を見ては意味、そのテーブルにユニークGamerIDされています各ゲーマーは、 neゲームですか? –

+0

@Naveenはいそうです。私はその例を実際のテーブルのアナログにすることを意図していたので、細部を省略することができます。 – Morpork

+0

その後、ゲーマープレーヤーが複数のゲームをプレイしている場合、そのテーブルはそのケースを処理しません。 –

答えて

6

この試してみてください:あなたが行うことができ、他のオプションは、サブクエリを好きではない場合は(一時テーブルやビューを作成することです

+---------+--------+-------+ 
| gamerid | gameid | score | 
+---------+--------+-------+ 
|  4 |  1 | 90 | 
|  5 |  2 | 40 | 
|  8 |  3 | 30 | 
+---------+--------+-------+ 
3 rows in set (0.00 sec) 

SELECT gamers.* 
FROM gamers 
INNER JOIN 
(SELECT 
    max(score) as maxscore, 
    gameid from gamers 
    GROUP BY gameid) AS b 
ON (b.gameid = gamers.gameid AND b.maxscore=gamers.score) ; 
ORDER BY score DESC, gameid; 

この意志の出力を)。その後

create temporary table games_score (
SELECT max(score) as maxscore, gameid FROM gamers GROUP BY gameid 
); 

SELECT gamers.* 
FROM gamers 
INNER JOIN games_score AS b ON (b.gameid = gamers.gameid AND b.maxscore=gamers.score) 
ORDER BY score DESC, gameid; 

またはビュー:次に

create or replace view games_score AS 
SELECT max(score) as maxscore, gameid FROM gamers GROUP BY gameid; 

SELECT gamers.* 
FROM gamers 
INNER JOIN games_score AS b ON (b.gameid = gamers.gameid AND b.maxscore=gamers.score) 
ORDER BY score DESC, gameid; 
+0

ありがとうございました。それは0.12秒かかった。私はこれが以前のクエリによって引き起こされたかどうか疑問に思っていますか? – Morpork

+0

@Morporkクエリ/結果セットがキャッシュされている可能性があります。一時的なビューまたはビューは、データをより速くロードする必要があります –

+0

私はこれを疑い、すべての4つの回答を再送します。撮影に要した時間は全員で同じでした。それをどうしたらいいか分からない。キャッシュのために2回目の実行がより高速になることを期待していました。 (私がmysql haha​​について知っていることを示しています) – Morpork

1

あなたは、これがサブ選択、以下のように使用して実行できます。

SELECT GameID, GamerID, Score 
FROM Gamers 
WHERE Score = (
    SELECT 
    MAX(scores.Score) 
    FROM Gamers AS scores 
    WHERE scores.GameID = Gamers.GameID 
) 
GROUP BY GameID 
でテスト

:もちろん

CREATE TABLE Gamers (
    GamerID int(11) NOT NULL, 
    GameID int(11) NOT NULL, 
    Score int(11) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

INSERT INTO Gamers (GamerID, GameID, Score) VALUES 
(1, 1, 10), 
(2, 1, 10), 
(3, 1, 10), 
(4, 1, 90), 
(5, 2, 40), 
(6, 2, 10), 
(7, 3, 10), 
(8, 3, 10); 

これは2人のゲーマーが与えられたゲームのために同じスコアを達成状況では理想的ではないだろう。

+2

これはすべての行を返します。 – CincauHangus

+1

@CincauHangusあなたが正しいです - 私は私の答えを削除し、その後、より多くの考えを改訂しました。 –

+0

ありがとう、これは働いた。私の〜1300行のテーブルでは18.3秒かかりました。 (テーブルには追加のものもたくさんあります) – Morpork

4

これを試してみてください。

SELECT a.GameID, a.GamerID, a.Score 
FROM Gamers a INNER JOIN 
    (
     SELECT s.GameID, MAX(s.Score) AS Maxx 
     FROM Gamers s 
     GROUP BY s.GameID 
    ) b ON (a.GameID = b.GameID) AND (a.Score = b.Maxx) 
ORDER BY GameID; 
+0

ありがとう、これも動作します。 – Morpork

4

はこれを試してみてください:データを提供与え

select g1.* from gamers g1 
left join gamers g2 
on g1.gameId = g2.gameId and g1.score < g2.score 
where g2.score is null 

結果:

+---------+--------+-------+ 
| GAMERID | GAMEID | SCORE | 
+---------+--------+-------+ 
|  4 |  1 | 90 | 
|  5 |  2 | 40 | 
|  8 |  3 | 30 | 
+---------+--------+-------+ 
+0

しかし、 '(gamerid、gameid、score)=(9,3,30)'などのネクタイがあればどうなりますか?そのような状況の方針はもちろん明記されていませんが、それでも起こる可能性があります。 –

+1

両方の結果が最大値になるため、両方の結果が返されます。 –

+0

ありがとう、これは動作します。これを私の何千もの行のテーブルで走らせると、9秒かかりましたが、@ johntotetwooのソリューションを実行すると、0.89秒かかりました。これはクエリのためか、ソリューションを先に実行したためですか? – Morpork

関連する問題