版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_36564655/article/details/81747504
求每个分组中的最大值
问题可参考https://segmentfault.com/q/1010000004138670
mysql> select * from test;
+----+-------+-----+-------+
| id | name | age | class |
+----+-------+-----+-------+
| 1 | wang | 11 | 3 |
| 2 | qiu | 22 | 1 |
| 3 | liu | 42 | 1 |
| 4 | qian | 20 | 2 |
| 5 | zheng | 20 | 2 |
| 6 | li | 33 | 3 |
+----+-------+-----+-------+
问题:如何选出每班年龄最大者?要求返回符合要求的一行
- 尝试一:
selecet id,name,Max(age),class from test group by class
上面这个写法是错误的,因为
包含group by 的SQL语句,select的列要么是聚合函数,要么只能出现在group by 子句中
而id和name不满足要求,返回的结果会错位。
- 尝试二:group by + join方式
select t1.id,name,t1.age,t1.class from test as t1,
(select class,Max(age)as age from test group by class)as t2
where t1.class= t2.class and t1.age = t2.age
这条语句引用了两个表(t1 和 t2),语义上相当于内连接(INNER JOIN)。子查询可以作为一个一次性的视图(子查询必须用括号括起来,一般后面接”as 表名”来将子查询的结果保存下来 )
- 尝试三: 对尝试二进行优化,一般join的时候小表在前,大表在后
select t1.id,name,t1.age,t1.class from
(select Max(age)as age,class from test group by class)as t2
inner join test t1 on t1.age = t2.age and t1.class = t2.class
- 尝试四:另一种子查询方式–嵌套子查询
select t1.id,name,t1.age,t1.class from test t1
where t1.age = (select max(age) from test t2 where t2.class = t1.class)
总结
- 上述尝试二、三、四均正确,均可以返回最大值有多条情况时的记录。
- 在SQL语句中,含有子查询一般比较慢,应该尽量避免使用子查询,所以尝试四要比尝试二、三慢,应该尽量使用尝试二、三(即join+group by的形式)
关于Group by
在使用分组和聚合函数时,SELET子句中只能存在以下三种元素:
(1)常数
(2)聚合函数
(3)GROUP BY 子句中指定的列名
在 GROUP BY 子句中不能使用列的别名。
GROUP BY 子句结果的显示是无限的。
只有 SELECT 子句和 HAVING 子句中能够使用聚合函数,特别是 WHERE 子句中无法使用。
参考链接
https://segmentfault.com/q/1010000004138670
https://segmentfault.com/a/1190000004157112
https://www.jianshu.com/p/47568113fe73