为什么MySQL允许"分组"查询没有聚合函数?

Aar*_* Fi 59 mysql sql standards-compliance ansi-sql

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

select X, Y from someTable group by X
Run Code Online (Sandbox Code Playgroud)

如果您在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.
Run Code Online (Sandbox Code Playgroud)

那么MySQL如何确定每个X显示哪个Y?它只选了一个.据我所知,它只是挑选它找到的第一个Y. 理由是,如果Y既不是聚合函数也不是group by子句,那么在查询中指定"select Y"就没有意义.因此,我作为数据库引擎将返回我想要的任何内容,你会喜欢它.

甚至还有一个MySQL配置参数来关闭这种"松散". 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是这样设计的?打破ANSI-SQL的理由是什么?

小智 23

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


Ceb*_*yre 20

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

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
Run Code Online (Sandbox Code Playgroud)

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

  • @gbn:垃圾到底是什么?如果在user.id上有PK,那么使用类似`SELECT user.id,ANY(user.name).. GROUP BY user.id`这样的东西并不是不确定的.显然,从中获取的存储桶user.name将包含一个唯一值 - 其id被分组的用户的名称.使用'MAX(user.name)AS name`或任何其他aggragate充其量是尴尬的(尽管意图更清楚地记录).可能是"依赖于"的情况再次.. (6认同)
  • GROUP BY子句中的较少列意味着更快的执行时间,因此它是一个优化的黑客.我在ANSI SQL实现的类似查询中有点使用`MAX(user.name)AS name`. (2认同)
  • AFAIK 最新的 SQL 标准要求所有选定的字段是组字段或聚合字段或为组确定的字段,例如上面示例中的 user.name。因此 MySQL 符合最新标准,因为它们允许您选择既不是组字段也不是聚合字段但确定组的字段 - 这是许多其他 dbms 不允许的。但是,MySQL 不检查字段是否真的是确定的,从而违反了标准合规性,因此也允许不确定的字段。[未完待续] (2认同)

归档时间:

查看次数:

22955 次

最近记录:

5 年,11 月 前