一尘不染

MySQL-选择不在分组依据中的列

mysql

我正在尝试向先前存在的应用程序中添加功能,并且遇到了如下MySQL视图:

SELECT
     AVG(table_name.col1),
     AVG(table_name.col2),
     AVG(table_name.col3),
     table_name.personID,
     table_name.col4
FROM table_name
GROUP BY table_name.personID;

好,所以有一些聚合函数。您可以选择personID,因为您正在对其进行分组。但是它还会选择不在聚合函数中并且不属于GROUP
BY子句的列。这怎么可能???它是否只是选择一个随机值,因为每个组中的值肯定不是唯一的?

我来自(MSSQL Server),那是一个错误。有人可以向我解释此行为以及为什么它在MySQL中被允许吗?


阅读 408

收藏
2020-05-17

共1个答案

一尘不染

的确,此功能允许一些模棱两可的查询,并且以静默方式返回结果集,并从该列中选择一个任意值。实际上,它往往是该组中的行中的值首先被物理存储。

如果您仅选择功能上依赖于GROUP
BY条件中的列的列,则这些查询并不是明确的。换句话说,如果每个用于定义该组的值的“歧义”列中只有一个不同的值,则没有问题。此查询在Microsoft SQL
Server(和ANSI SQL)中将是非法的,即使它不能在逻辑上导致歧义:

SELECT AVG(table1.col1), table1.personID, persons.col4
FROM table1 JOIN persons ON (table1.personID = persons.id)
GROUP BY table1.personID;

另外,MySQL具有SQL模式以使其符合标准:
ONLY_FULL_GROUP_BY

FWIW,SQLite也允许这些模棱两可的GROUP BY子句,但是它从组的 最后 一行选择值。†


†至少在我测试的版本中。表示 任意性的意思
是,MySQL或SQLite将来都可能更改其实现,并具有一些不同的行为。因此,在这样的模棱两可的情况下,您不应该依赖行为保持当前状态。最好将查询重写为确定性的,而不是模棱两可的。这就是为什么MySQL
5.7现在默认情况下启用ONLY_FULL_GROUP_BY的原因。

2020-05-17