timg.jpeg
本节将简单介绍分组数据,以便能汇总表内容的子集
分组数据
select sid, avg(score)
from sc
group by sid;
此查询语句返回了每个学生的平均分,输出为:
+------+------------+
| sid | avg(score) |
+------+------------+
| 01 | 73.00000 |
| 02 | 70.00000 |
| 03 | 80.00000 |
| 04 | 63.33333 |
| 05 | 81.50000 |
| 06 | 32.50000 |
| 07 | 93.50000 |
+------+------------+
使用 WITH ROLLUP 关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值,如
select sid, avg(score)
from sc
group by sid with rollup;
此查询语句返回了所有学生各自的平均分,以及所有学生的平均分,输出为:
+------+------------+
| sid | avg(score) |
+------+------------+
| 01 | 73.00000 |
| 02 | 70.00000 |
| 03 | 80.00000 |
| 04 | 63.33333 |
| 05 | 81.50000 |
| 06 | 32.50000 |
| 07 | 93.50000 |
| NULL | 70.77778 |
+------+------------+
在具体使用 group by 子句前,需要知道一些重要的规定:
group by 子句可以包含任意数目的列。这使得能对分组进行嵌套,为数据分组提供更细致的控制
如果在 group by 子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)
group by 子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在 select 中使用表达式,则必须在 group by 子句中指定相同的表达式。不能使用别名
除聚集计算语句外, select 语句中的每个列都必须在 group by 子句中给出
如果分组列中具有 null 值,则 null 将作为一个分组 返回。如果列中有多行 null 值,它们将分为一组
group by 子句必须出现在 where 子句之后, order by 子句之前
过滤数组
这里有另一种理解方法,where 在数据分组前进行过滤, having 在数据分组后进行过滤。这是一个重要的区别, where 排除的行不包括在分组中。这可能会改变计算值,从而影响 having 子句中基于这些值过滤掉的分组
select sid, avg(score) as score_avg
from sc
group by sid
having avg(score) > 70;
此查询语句返回了所有平均分大于 70 的数据,输出为:
+------+-----------+
| sid | score_avg |
+------+-----------+
| 01 | 73.00000 |
| 03 | 80.00000 |
| 05 | 81.50000 |
| 07 | 93.50000 |
+------+-----------+
如何在一个查询语句中既使用 where 有使用 having,语句如下:
select sid, avg(score)
from sc
where score > 60
group by sid
having avg(score) >= 80;
此查询语句返回了分数在 60 分以上的所有平均分大于等于 80 的学生,输出为:
+------+------------+
| sid | avg(score) |
+------+------------+
| 01 | 89.50000 |
| 03 | 80.00000 |
| 05 | 81.50000 |
| 07 | 93.50000 |
+------+------------+
分组和排序
一般在使用 group by 句时,应该也给出 order by 子句
比较类目
order by
group by
作用
排序产生的输出
分组行。但输出可能不是分组的顺序
使用范围
任意列都可以使用(甚至非选择的列也可以使用)
只可能使用选择列或表达式列,而且必须使用每个选择列表达式
是否一定需要
不一定需要
如果与聚集函数一起使用列(或表达式),则必须使用
select sid, avg(score)
from sc
group by sid
having avg(score) >= 60
order by avg(score);
此查询语句表示查询所有平均分大于等于 60 的学生,并按照平均分排序,输出为:
+------+------------+
| sid | avg(score) |
+------+------------+
| 04 | 63.33333 |
| 02 | 70.00000 |
| 01 | 73.00000 |
| 03 | 80.00000 |
| 05 | 81.50000 |
| 07 | 93.50000 |
+------+------------+
select 子句顺序
子句
说明
是否必须使用
select
要返回的列或表达式
是
from
从中检索数据的表
仅在从表选择数据时使用
where
行级过滤
否
group by
分组说明
仅在按组计算聚集时使用
having
组级过滤
否
order by
输出排序顺序
否
limit
要检索的行数
否