猿问

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

我有一个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)


肥皂起泡泡
浏览 997回答 3
3回答

慕标5832272

在这一点上阅读MySQL文档。简而言之,MySQL出于性能考虑,允许从GROUP BY中删除某些列,但是,只有在被省略的列都具有相同值(在分组内)的情况下,此方法才有效,否则,查询返回的值的确是不确定的,例如在这篇文章中被其他人正确猜到了。确保添加ORDER BY子句不会重新引入任何形式的确定性行为。尽管不是问题的核心,但本示例说明如何使用*而不是对所需列进行显式枚举通常是一个坏主意。摘自MySQL 5.0文档:使用此功能时,每个组中的所有行应具有相同的值对于GROUP BY部分中省略的列。服务器是免费的从组中返回任何值,因此结果是不确定的,除非所有值都相同。 

至尊宝的传说

这有点晚了,但我会提出来供将来参考。GROUP BY接收具有重复项的第一行,并丢弃结果集中第二行之后的所有匹配行。因此,如果杰克和汤姆具有相同的部门,则在普通SELECT中首先出现的人将是GROUP BY中的结果行。如果要控制列表中第一个出现的内容,则需要执行ORDER BY。但是,SQL不允许ORDER BY出现在GROUP BY之前,因为它将引发异常。解决此问题的最佳方法是在子查询中执行ORDER BY,然后在外部查询中执行GROUP BY。这是一个例子:SELECT * FROM (SELECT * FROM emp ORDER BY name) as foo GROUP BY dept这是我发现的性能最好的技术。我希望这可以帮助某人。

慕容708150

我发现最好的办法是考虑不支持这种类型的查询。在大多数其他数据库系统中,不能在GROUP BY子句中或HAVING,SELECT或ORDER BY子句中的聚合函数中都不包含列。相反,请考虑您的查询读取:SELECT ANY(name), dept, ANY(salary)FROM emp GROUP BY dept;...因为这是怎么回事。希望这可以帮助....
随时随地看视频慕课网APP
我要回答