我有一个emp
包含以下结构和数据的表:
name dept salary
----- ----- -----
Jack a 2
Jill a 1
Tom b 2
Fred b 1
Run Code Online (Sandbox Code Playgroud)
当我执行以下SQL时:
SELECT * FROM emp GROUP BY dept
Run Code Online (Sandbox Code Playgroud)
我得到以下结果:
name dept salary
----- ----- -----
Jill a 1
Fred b 1
Run Code Online (Sandbox Code Playgroud)
在什么基础上服务器决定返回吉尔和弗雷德并排除杰克和汤姆?
我在MySQL中运行此查询.
注1:我知道查询本身没有意义.我试图用'GROUP BY'方案调试问题.我试图理解为此目的的默认行为.
注2:我习惯于编写与GROUP BY子句相同的SELECT子句(减去聚合字段).当我遇到上述行为时,我开始想知道我是否可以依赖于以下场景:从emp表中选择薪水是dept中最低/最高的行.例如:像这样的SQL语句适用于MySQL:
SELECT A.*, MIN(A.salary) AS min_salary FROM emp AS A GROUP BY A.dept
Run Code Online (Sandbox Code Playgroud)
我没有找到任何描述这种SQL工作原理的材料,更重要的是如果我能够始终如一地依赖这种行为.如果这是一个可靠的行为,那么我可以避免以下查询:
SELECT A.* FROM emp AS A WHERE A.salary = (
SELECT MAX(B.salary) FROM emp B WHERE B.dept = A.dept)
Run Code Online (Sandbox Code Playgroud)
mjv*_*mjv 36
阅读关于这个特定点的MySQL文档.
简而言之,出于性能目的,MySQL允许省略GROUP BY中的某些列,但是只有当省略的列都具有相同的值(在分组中)时,这才有效,否则,查询返回的值确实是不确定的,如在这篇文章中被其他人恰当地猜到了.确保添加ORDER BY子句不会重新引入任何形式的确定性行为.
虽然不是问题的核心,但这个例子说明了如何使用*而不是显式枚举所需列通常是一个坏主意.
摘自MySQL 5.0文档:
When using this feature, all rows in each group should have the same values for the columns that are omitted from the GROUP BY part. The server is free to return any value from the group, so the results are indeterminate unless all values are the same.
小智 10
这有点晚了,但我会把它放在以后参考.
GROUP BY获取具有重复的第一行,并丢弃在结果集中匹配的任何行.因此,如果Jack和Tom拥有相同的部门,那么在普通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
Run Code Online (Sandbox Code Playgroud)
这是我发现的最佳表现技术.我希望这可以帮助别人.