如果没有指定聚合函数,MySQL 会做什么?
What does MySQL do if no aggregating function specified?
最近我发现尽管 patientID
在我的 Samples
table 中重复,但以下查询有效
SELECT * FROM Samples GROUP BY patientID
和 returns 多个列的多个值。
默认使用什么聚合函数?
您有两个使用聚合函数,例如 SUM、AVG、COUNT
dev.mysql GROUP BY
MySQL 似乎根本没有使用聚合函数。在这种情况下选择的记录是不确定的,如 documentation 所述:
In this case, the server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate, which is probably not what you want.
但您可能想知道为什么这个功能一开始就存在。如果您正在编写一个查询,其中您知道列中的所有值都是相同的,那么此功能可能会为您节省一些工作,因为您不必编写连接或子查询来使 GROUP BY
严格兼容。
首先,它的格式很糟糕 SQL,你不应该使用它。
但是它有什么作用呢?它 returns 一个结果集,每个 PatientId
一行。 SELECT *
指定的附加列来自数据中的 indeterminate 行。无法保证额外的列甚至来自同一行。
实际上,值似乎来自遇到的第一行。但是,MySQL 非常明确地表明您不能依赖此行为。通常,您应该避免使用在 SELECT
中具有未聚合列但不在 GROUP BY
中的聚合语句。其他数据库不支持此语法(除非 GROUP BY
键在聚合数据上形成 unique/primary 键)。
None。如果 ONLY_FULL_GROUP_BY sql mode is not enabled, then MySQL allows
MySQL extension to the standard SQL use of GROUP BY permits the select list, HAVING condition, or ORDER BY list to refer to nonaggregated columns even if the columns are not functionally dependent on GROUP BY columns. This causes MySQL to accept the preceding query. In this case, the server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate, which is probably not what you want.
此 sql 模式仅在 rom v5.7.5 中默认启用。
由于您没有指定 MySQL 服务器的版本,因此有两种可能的答案。
之前 MySQL 5.7.5,上面的查询是有效的,但是对于所有没有在 GROUP BY 中列出也没有聚合的列有以下注释:
The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate.
(https://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html)
自 MySQL 5.7.5 起,此行为已更改并且 MySQL 实现了 SQL99 标准:
SQL99 and later permits such nonaggregates per optional feature T301 if they are functionally dependent on GROUP BY
columns
(https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html)
因此某些列可能有效,但查询本身无效,因为并非所有列在功能上都依赖于 patientID 列(可能同时存在血液和皮肤样本)。
一般来说,使用 SELECT *
并且不定义如何处理聚合查询中的所有结果列是一种不良行为。
TL;DR;
MySQL5.7.5之前会执行查询,结果不可预知,MySQL5.7.5之后会报错。
最近我发现尽管 patientID
在我的 Samples
table 中重复,但以下查询有效
SELECT * FROM Samples GROUP BY patientID
和 returns 多个列的多个值。
默认使用什么聚合函数?
您有两个使用聚合函数,例如 SUM、AVG、COUNT dev.mysql GROUP BY
MySQL 似乎根本没有使用聚合函数。在这种情况下选择的记录是不确定的,如 documentation 所述:
In this case, the server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate, which is probably not what you want.
但您可能想知道为什么这个功能一开始就存在。如果您正在编写一个查询,其中您知道列中的所有值都是相同的,那么此功能可能会为您节省一些工作,因为您不必编写连接或子查询来使 GROUP BY
严格兼容。
首先,它的格式很糟糕 SQL,你不应该使用它。
但是它有什么作用呢?它 returns 一个结果集,每个 PatientId
一行。 SELECT *
指定的附加列来自数据中的 indeterminate 行。无法保证额外的列甚至来自同一行。
实际上,值似乎来自遇到的第一行。但是,MySQL 非常明确地表明您不能依赖此行为。通常,您应该避免使用在 SELECT
中具有未聚合列但不在 GROUP BY
中的聚合语句。其他数据库不支持此语法(除非 GROUP BY
键在聚合数据上形成 unique/primary 键)。
None。如果 ONLY_FULL_GROUP_BY sql mode is not enabled, then MySQL allows
MySQL extension to the standard SQL use of GROUP BY permits the select list, HAVING condition, or ORDER BY list to refer to nonaggregated columns even if the columns are not functionally dependent on GROUP BY columns. This causes MySQL to accept the preceding query. In this case, the server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate, which is probably not what you want.
此 sql 模式仅在 rom v5.7.5 中默认启用。
由于您没有指定 MySQL 服务器的版本,因此有两种可能的答案。
之前 MySQL 5.7.5,上面的查询是有效的,但是对于所有没有在 GROUP BY 中列出也没有聚合的列有以下注释:
The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate.
(https://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html)
自 MySQL 5.7.5 起,此行为已更改并且 MySQL 实现了 SQL99 标准:
SQL99 and later permits such nonaggregates per optional feature T301 if they are functionally dependent on
GROUP BY
columns
(https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html)
因此某些列可能有效,但查询本身无效,因为并非所有列在功能上都依赖于 patientID 列(可能同时存在血液和皮肤样本)。
一般来说,使用 SELECT *
并且不定义如何处理聚合查询中的所有结果列是一种不良行为。
TL;DR; MySQL5.7.5之前会执行查询,结果不可预知,MySQL5.7.5之后会报错。