2012-05-05 49 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

这个伎俩,非常感谢你!我会给你信誉的,希望用户会喜欢! :) –