标准SQL会拒绝你的查询,因为你 无法选择非集合字段 是 不是该组的一部分BY子句 在聚合查询
这是 正确的,直到1992年 。
但是 ,从2003年及以后, 这是完全 错误的。
根据SQL-2003标准
6IWD6-02-Foundation-2011-01.pdf,来自http://www.wiscorp.com/
,第7.12段(查询规范),第398页:
17)如果T是一个分组表,则让G是T的分组列的集合。在[[选择列表])中包含的每个[[值表达式]]中,每个引用T列的列引用都应引用一些在
功能上依赖 于G的列C 或 应 包含在 聚合查询为QS的(((set函数规范))的聚合 参数 中
现在MYSQL,通过允许实现此功能 不仅 是列 函数依赖 于分组列 ,但 允许 所有列
。这给用户带来了一些问题,这些用户不了解分组的工作方式,并在他们意想不到的地方获得不确定的结果。
但是您说的很对,MySQL添加了与SQL标准冲突的功能(尽管您似乎出于错误的原因而认为)。由于他们添加了SQL标准功能,但并不是以最佳方式(更像是简单的方式),这并不完全准确,但确实与最新标准相冲突。
为了回答您的问题,我认为此MySQL功能(扩展名)的原因是符合最新的SQL标准(2003+)。为什么他们选择以这种方式实现它(不完全兼容),我们只能推测。
正如@Quassnoi和@Johan举例说明的那样,这主要是性能和可维护性问题。但是无法轻易地将RDBMS更改为足够聪明(不包括Skynet)以识别功能相关列,因此MySQL开发人员做出了选择:
我们(MySQL)为您(MySQL用户)提供了SQL-2003标准中的此功能。它可以提高某些
GROUPBY查询的速度,但有一个问题。您必须小心(而不是SQL引擎),因此SELECTandHAVINg列表中的列在功能上取决于GROUPBY列。如果没有,您可能会得到不确定的结果。如果要禁用它,可以设置
sql_mode为ONLY_FULL_GROUP_BY。
一切都在MySQL的文档中:
GROUPBY(5.5)的扩展
-尽管不在上面的措辞中,但正如您的引用一样(他们甚至忘记提及它与标准SQL-2003的差异,而不是与标准SQL-92的差异)。我认为这种选择在所有软件(包括其他RDBMS)中都是常见的。它们是出于性能,向后兼容性和许多其他原因而制造的。
''is the same as NULL例如,Oracle有名,SQL-Server也可能有一些。
彼得·布曼(Peter Bouman)的博客文章也捍卫了MySQL开发人员的选择:Debunking GROUP BY
myths。
更新(2011)
正如@Mark Byers在评论中(在DBA.SE的一个相关问题中)告知我们的那样, PostgreSQL
9.1添加了一个
为此目的而设计
的新功能
(发布日期:2011年9月)。它比MySQL的实施更具限制性,并且更接近于标准。
更新2(2015)
MySQL宣布在5.7版本中改进了行为,使其符合标准并实际上识别了功能依赖性(甚至比Postgres实现更好)。文档:MySQL处理
GROUPBY(5.7)和Peter Bouman的另一篇博客文章:MySQL 5.7.5:
GROUPBY尊重功能依赖!


![MySQL为什么要添加与SQL标准冲突的功能?[关闭] MySQL为什么要添加与SQL标准冲突的功能?[关闭]](http://www.mshxw.com/aiimages/31/408114.png)
