2012-02-17 94 views
2

假設我有一個名爲Gamers的表格。 遊戲玩家包含列GamerID,GameID,Scoremysql在單個表格中選擇每個類別的最佳

我有興趣選擇每場比賽得分最高的球員。

例如,

|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在該表中,意義獨特每個玩家只玩o ne遊戲? – 2012-02-17 07:00:50

+0

@Naveen是的。我打算將這個例子作爲我實際表格的一個模擬,所以我可以省略一大堆細節。 – Morpork 2012-02-17 07:04:44

+0

那麼當遊戲玩家玩多個遊戲時,該表格不會處理這種情況。 – 2012-02-17 07:32:12

回答

6

試試這個:

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; 

這將輸出:

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

你可以做的另一種選擇是創建臨時表或視圖(如果你不喜歡子查詢)。

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 2012-02-17 03:44:57

+0

@Morpork查詢/結果集很可能被緩存,這可能是爲什麼。臨時或視圖應加載更快的數據 – 2012-02-17 03:53:24

+0

我懷疑這一點,並reran所有4個答案。所花的時間對每個人都是一樣的。不知道該怎麼做。我預計第二輪運行會因爲緩存而變得更快。 (顯示我所知道的關於mysql哈哈) – Morpork 2012-02-17 03:55:36

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

雖然會返回所有行。 – CincauHangus 2012-02-17 02:54:15

+1

@CincauHangus你是對的 - 我刪除了我的答案,然後在經過更多考慮後修改了它。 – 2012-02-17 03:10:24

+0

謝謝,這工作。不過,我的〜1300排桌上花了18.3秒。 (該表還有一堆額外的東西) – Morpork 2012-02-17 03:41:37

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 2012-02-17 03:38:14

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)'這樣的配合會發生什麼?這種情況的政策當然沒有說明,但它仍然可以發生。 – 2012-02-17 03:05:44

+1

兩個結果都會返回,因爲兩個結果都是最大值。 – 2012-02-17 03:09:46

+0

謝謝,這個工程。當我在我的千行表上運行這個時,它耗時9秒,但是當我運行@johntotetwoo的解決方案時,耗時0.89秒。這是因爲查詢還是因爲我先運行了解決方案? – Morpork 2012-02-17 03:37:35