2012-05-05 108 views
2

在網站上搜索了幾個小時後,我無法找到正確的答案來解決問題,或者答案很複雜。 我有一些統計數據,來自minecraftserver,我想知道哪些塊是由誰創建的。所以我開始使用GROUP BY和MAX,但它沒有返回正確的值。 MAX值是好的,但它與itemid和playerid衝突。它只是選擇第一個id和玩家名稱。 (注:每個playerid有一個單獨的一行爲每個項目!!!)查詢是如下:MAX和GROUP BY不會返回好值

SELECT `playername` , `itemid` , MAX(destroyed) 
FROM `blockstats_typed` 
GROUP BY `itemid` 
LIMIT 0 , 30 

是有playername字段,ITEMID,創建和銷燬。我希望你們能幫助我...

如果你需要更多信息,就這麼說!

編輯1(表模式):

id   int(10)   id of the row (AI) 
playername varchar(50)  playername 
itemid  smallint(5)  id of the item 
created  int(10)   times created 
destroyed int(10)   times destroyed 
+1

您還需要通過'playername'進行分組。我很驚訝,沒有錯誤。 –

+1

只有MySQL(和PostgreSQL,但以更有限的方式)允許您省略選擇列表中但不包含聚合的GROUP BY子句中的列(表達式)。如果你想要項目ID,它被銷燬的最大次數,以及這樣做的用戶ID(或ID),你必須編寫一個更復雜的查詢。 –

+0

@JonathanLeffler:SQLite會讓MySQL「挑一個隨機的」東西,PostgreSQL讓你逃脫它,如果你是由PK分組和使用版本9.1+(AFAIK都)。 –

回答

1

只有MySQL和PostgreSQL(但PostgreSQL的確實它在一個非常有限的方式; 和評論告訴我,SQLite的模仿的MySQL在這個)允許您省略選擇列表中但不是聚合的GROUP BY子句中的列(表達式)。如果你想要項目ID,它被銷燬的最大次數,以及這樣做的用戶ID(或ID),你必須編寫一個更復雜的查詢。

所以,你可能會後:

SELECT playername, itemid, MAX(destroyed) 
    FROM blockstats_typed 
GROUP BY playername, itemid 
LIMIT 0, 30 

,或者您可能後:

SELECT b.PlayerName, s.ItemID, s.MaxDestroyed 
    FROM BlockStats_Typed AS b 
    JOIN (SELECT ItemID, MAX(Destroyed) AS MaxDestroyed 
      FROM BlockStats_Typed 
     GROUP BY ItemID 
     LIMIT 0, 30 
     ) AS s 
    ON b.ItemID = s.ItemID AND b.Destroyed = s.MaxDestroyed; 

需要注意的是,如果一些項目是由兩名球員破壞,比如說,237000次,你會得到支持雙方球員的名字(當然,如果該ItemID在前30名)。

兩者都是有效的查詢;但他們做了不同的事情。如果有的話,你必須決定哪些是你正在嘗試做的是正確的。如果兩者都不正確,你可能需要澄清你的問題。

(我不確定LIMIT是否允許在我寫的地方,如果沒有,請將它放在最後,也可以添加帶有DESC限定符的ORDER BY子句,以確保限制子句顯示最有趣的行; GROUP BY不保證排序。)

+0

這個伎倆,非常感謝你!我會給你信譽的,希望用戶會喜歡! :) –