为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

肥皂起泡泡 2019-10-11 10:04:04
我有一个emp具有以下结构和数据的表:name   dept    salary-----  -----   -----Jack   a       2Jill   a       1Tom    b       2Fred   b       1当我执行以下SQL:SELECT * FROM emp GROUP BY dept我得到以下结果:name   dept    salary-----  -----   -----Jill   a       1Fred   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)
查看完整描述

3 回答

?
慕标5832272

TA贡献1966条经验 获得超4个赞

在这一点上阅读MySQL文档。


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


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


摘自MySQL 5.0文档:


使用此功能时,每个组中的所有行应具有相同的值

对于GROUP BY部分中省略的列。服务器是免费的

从组中返回任何值,因此结果是不确定的,除非

所有值都相同。 


查看完整回答
反对 回复 2019-10-11
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

这有点晚了,但我会提出来供将来参考。


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

这是我发现的性能最好的技术。我希望这可以帮助某人。


查看完整回答
反对 回复 2019-10-11
?
慕容708150

TA贡献1831条经验 获得超4个赞

我发现最好的办法是考虑不支持这种类型的查询。在大多数其他数据库系统中,不能在GROUP BY子句中或HAVING,SELECT或ORDER BY子句中的聚合函数中都不包含列。


相反,请考虑您的查询读取:


SELECT ANY(name), dept, ANY(salary)

FROM emp 

GROUP BY dept;

...因为这是怎么回事。


希望这可以帮助....


查看完整回答
反对 回复 2019-10-11
  • 3 回答
  • 0 关注
  • 996 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信