MySQL GROUP BY行为(当使用带有order by的派生表时)

时间:2014-07-14 00:17:52

标签: mysql group-by derived

由于mysql没有强制执行Single-Value Rule(参见:https://stackoverflow.com/a/1646121/1688441),派生表是否会保证订单会显示哪些行值?这适用于不在聚合函数中但不在group by

中的列

在评论并回答了问题(MySQL GROUP BY behavior)后,我正在查看问题(https://stackoverflow.com/a/24653572/1688441)。

我不同意接受的答案,但意识到可能的改进答案是:

SELECT * FROM 
(SELECT * FROM tbl order by timestamp) as tb2
GROUP BY userID;

http://sqlfiddle.com/#!2/4b475/18

这是正确的还是mysql仍然会任意决定显示哪些行值?

1 个答案:

答案 0 :(得分:3)

此查询:

SELECT *
FROM (SELECT * FROM tbl order by timestamp) as tb2
GROUP BY userID;

依赖于扩展的MySQL组,记录为here。您特别依赖于所有列都来自同一行并遇到第一行的事实。 MySQL 特别警告不要做出这样的假设:

  

MySQL扩展了GROUP BY的使用,以便选择列表可以引用   未在GROUP BY子句中命名的非聚合列。这意味着   前面的查询在MySQL中是合法的。您可以使用此功能   通过避免不必要的列排序来获得更好的性能   分组。但是,这主要适用于每个中的所有值   GROUP BY中未命名的非聚合列对于每个列都是相同的   组。服务器可以自由选择每个组中的任何值,所以   除非它们相同,否则所选值不确定

所以,你不能依赖这种行为。这很容易解决。以下是一个示例查询:

select t.*
from tbl t
where not exists (select 1 from tbl t2 where t2.userid = t.userid and t2.timestamp > t.timestamp)

使用tbl(userid, timestamp)上的索引,这可能会更快。 MySQL在优化聚合方面做得非常糟糕。