我已经习惯了Microsoft技术,包括SQL Server。今天,我遇到了一个问答,其中引用了MySQL文档的以下内容:
标准SQL会拒绝您的查询,因为您不能在聚合查询中选择不属于GROUP BY子句的非聚合字段。MySQL扩展了GROUP BY的使用,以便选择列表可以引用未在GROUP BY子句中命名的非聚合列。这意味着前面的查询在MySQL中是合法的。您可以使用此功能来避免不必要的列排序和分组,从而获得更好的性能。但是,这主要在每个未聚合列中未在GROUP BY中命名的所有值对于每个组都相同时才有用。服务器可以从每个组中自由选择任何值,因此,除非它们相同,否则选择的值是 不确定的。
如果该MySQL扩展与SQL标准冲突,原因是什么?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
标准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标准中的此功能。它可以提高某些GROUP BY查询的速度,但有一个问题。您必须小心(而不是SQL引擎),因此SELECTand HAVING列表中的列在功能上取决于GROUP BY列。如果没有,您可能会得到不确定的结果。
如果要禁用它,可以设置sql_mode为ONLY_FULL_GROUP_BY。
一切都在MySQL的文档中:GROUP BY(5.5)的扩展 -尽管不在上面的措辞中,但正如您的引用一样(他们甚至忘记提及它与标准SQL-2003的差异,而不是与标准SQL-92的差异)。我认为这种选择在所有软件(包括其他RDBMS)中都是常见的。它们是出于性能,向后兼容性和许多其他原因而制造的。'' is the same as NULL例如,Oracle有名,SQL-Server也可能有一些。
彼得·布曼(Peter Bouman)的博客文章也捍卫了MySQL开发人员的选择:Debunking GROUP BY myths。来源:stack overflo