为什么MySQL允许“group by”查询WITHOUT聚合函数?

惊喜 – 这是在MySQL中完全有效的查询:

select X, Y from someTable group by X 

如果你在Oracle或SQL Server中试过这个查询,你会得到一个自然的错误信息:

 Column 'Y' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. 

那么MySQL如何确定为每个X显示哪个Y? 它只是select一个。 从我所知道的情况来看,它只是find了它find的第一个Y. 其基本原理是,如果Y既不是一个聚合函数,也不是在group by子句中,那么在查询中指定“select Y”是没有意义的。 因此,我作为数据库引擎将返回任何我想要的,你会喜欢它。

甚至有一个MySQLconfiguration参数来closures这个“松动”。 http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_only_full_group_by

这篇文章甚至提到了MySQL在这方面被ANSI-SQL不兼容的批评。 http://www.oreillynet.com/databases/blog/2007/05/debunking_group_by_myths.html

我的问题是: 为什么 MySQL这样devise? 他们违反ANSI-SQL的理由是什么?

我认为这是处理这样的情况,即一个字段的分组意味着其他字段也被分组:

 SELECT user.id, user.name, COUNT(post.*) AS posts FROM user LEFT OUTER JOIN post ON post.owner_id=user.id GROUP BY user.id 

在这种情况下,user.name将始终是唯一的每个user.id,所以在GROUP BY子句中不需要user.name是方便的(虽然,如你所说,有问题的确定的范围)

根据这个页面 (5.0在线手册),这是为了更好的性能和用户的方便。

不幸的是,几乎所有的SQL变种都有可能破坏ANSI并且产生不可预知的结果。

这听起来像他们希望它被视为许多其他系统具有的“FIRST(Y)”function。

这个结构很可能是MySQL团队所遗憾的,但是由于会破坏的应用程序的数量而不想停止支持。

当你使用没有聚合函数的GROUP BY时,MySQL把这看作是单列DISTINCT。 使用其他选项,您可以将整个结果清晰化,或者必须使用子查询等。问题是结果是否真正可预测。

此外,在这个线程好信息。

从我在mysql参考页面读到的内容,它说: “你可以使用这个特性来避免不必要的列sorting和分组,从而获得更好的性能。但是,这非常有用,当每个非聚集列中的所有值未在GROUP BY对于每个组都是一样的。“

我build议你阅读这个页面(链接到MySQL的参考手册): http : //dev.mysql.com/doc/refman/5.5/en//group-by-extensions.html

它实际上是一个非常有用的工具,所有其他领域不必在聚合function,当你由一个字段分组。 你可以通过简单的sorting来处理返回的结果,然后将其分组。 例如,如果我想获得用户login信息,我想看到用户最后一次login,我会做到这一点。

 USER user_id | name USER_LOGIN_HISTORY user_id | date_logged_in 

USER_LOGIN_HISTORY对于一个用户有多行,所以如果我join用户,它将返回许多行。 因为我只对最后一个条目感兴趣,所以我会这样做

 select user_id, name, date_logged_in from( select u.user_id, u.name, ulh.date_logged_in from users as u join user_login_history as ulh on u.user_id = ulh.user_id where u.user_id = 1234 order by ulh.date_logged_in desc )as table1 group by user_id 

这将返回一行用户的名称和用户最后一次login。