MAX和GROUP BY不返回好的值

时间:2012-05-05 00:41:53

标签: mysql group-by max

在网站上搜索了几个小时后,我找不到问题的正确答案,或答案很复杂。 我有一些统计数据,来自一个minecraft服务器,我想知道哪些块是由谁创建的。所以我从GROUP BY和MAX开始,但它没有返回正确的值。 MAX值很好,但它与itemid和playerid冲突。它只选择第一个id和播放器名称。 (注意:每个玩家都有一个单独的行!!!)查询如下:

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 个答案:

答案 0 :(得分:1)

只有MySQL和PostgreSQL(但PostgreSQL以更有限的方式完成它; 并且注释告诉我SQLite模仿这个中的MySQL)允许你省略GROUP BY中的列(表达式) select-list中的子句但不是聚合。如果您想要项目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;

请注意,如果某个项目被两个玩家销毁了237,000次,那么你将获得两个玩家的名字(当然,如果ItemID在前30名中),那么。

两者都是有效的查询;但他们做了不同的事情。你必须决定哪一个(如果有的话)对你正在做的事情是正确的。如果两者都不正确,您可能需要澄清您的问题。

(我不确定LIMIT是否在我编写的地方被允许。如果没有,请将其放在最后。并且您可能希望添加带有DESC限定符的ORDER BY子句以确保限制子句显示最有趣的行; GROUP BY不保证排序。)