一尘不染

SELECT子句中不存在聚合函数时的GROUP BY行为

mysql

我有一个emp具有以下结构和数据的表:

name   dept    salary
-----  -----   -----
Jack   a       2
Jill   a       1
Tom    b       2
Fred   b       1

当我执行以下SQL:

SELECT * FROM emp GROUP BY dept

我得到以下结果:

name   dept    salary
-----  -----   -----
Jill   a       1
Fred   b       1

服务器是基于什么决定决定返回吉尔和弗雷德,并排除杰克和汤姆?

我在MySQL中运行此查询。

注意1:我知道查询本身没有任何意义。我正在尝试调试“ GROUP BY”方案的问题。我试图了解用于此目的的默认行为。

注2:我习惯于编写与GROUP
BY子句相同的SELECT子句(减去聚合字段)。当我遇到上述行为时,我开始怀疑我是否可以在以下情况下依赖此行为:从emp表中选择薪水在部门中最低/最高的行。例如:这样的SQL语句可在MySQL上运行:

SELECT A.*, MIN(A.salary) AS min_salary FROM emp AS A GROUP BY A.dept

我找不到任何描述这种SQL为何起作用的材料,更重要的是,如果我能够始终如一地依靠这种行为的话。如果这是可靠的行为,那么我可以避免类似以下的查询:

SELECT A.* FROM emp AS A WHERE A.salary = ( 
            SELECT MAX(B.salary) FROM emp B WHERE B.dept = A.dept)

阅读 397

收藏
2020-05-17

共1个答案

一尘不染

在这一点上阅读 MySQL文档

简而言之,MySQL出于性能考虑,允许从GROUP BY中 _ 删除 某些列,但是, _只有 在被省略的列都具有相同值
(在分组内)的情况下, 此方法才有效 ,否则, 查询返回的值的确是不确定的 ,例如在这篇文章中被其他人正确猜到了。确保添加ORDER
BY子句不会重新引入任何形式的确定性行为。

尽管不是问题的核心,但本示例说明如何使用*而不是对所需列进行显式枚举通常是一个坏主意。

摘自MySQL 5.0文档:

使用此功能时,每个组中的所有行应具有相同的值
对于GROUP BY部分中省略的列。服务器是免费的
从组中返回任何值,因此结果是不确定的,除非
所有值都相同。
2020-05-17