Mysql 的分组数据(十)

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 子句前,需要知道一些重要的规定:

  1. group by 子句可以包含任意数目的列。这使得能对分组进行嵌套,为数据分组提供更细致的控制
  2. 如果在 group by 子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)
  3. group by 子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在 select 中使用表达式,则必须在 group by 子句中指定相同的表达式。不能使用别名
  4. 除聚集计算语句外, select 语句中的每个列都必须在 group by 子句中给出
  5. 如果分组列中具有 null 值,则 null 将作为一个分组 返回。如果列中有多行 null 值,它们将分为一组
  6. 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 要检索的行数

你可能感兴趣的:(Mysql 的分组数据(十))