本节要点

汇总统计
分组汇总统计

汇总统计

对于深圳市第一中学的所有学生,考虑以下查询需求:

(1)、深圳市第一中学总共有多少名学生?

(2)、所有学生的数学成绩总和是多少?

(3)、所有学生的数学成绩最高分是多少?

(4)、所有学生的数学成绩最低分是多少?

(5)、所有学生的数学成绩的平均分是多少?

对于这一类查询,就需要用到本节课讲解的聚合函数。

常用的聚合函数有五个:

COUNT:计数

SUM:求和

MAX:求最大

MIN:求最小

AVG:求平均

那么上面这五个查询需求,可以写出SQL语句如下:

SELECT COUNT(*) FROM student; --总共有多少名学生?
SELECT SUM(score) FROM student; --所有学生的数学成绩总和?
SELECT MAX(score) FROM student; --所有学生的数学成绩最高分?
SELECT MIN(score) FROM student; --所有学生的数学成绩最低分?
SELECT AVG(score) FROM student; --所有学生的数学成绩平均分?

关于COUNT聚合函数的使用,还有以下几种写法:

SELECT COUNT(score) FROM student;
SELECT COUNT(student_id) FROM student;
SELECT COUNT(1) FROM student;
SELECT COUNT('ABC') FROM student;

在score、student_id的值不存在NULL值的情况下,它们返回的结果与下面这个SQL是一样的。

SELECT COUNT(*) FROM student;

所以说,在COUNT后面跟上字段,或者跟上一个固定值,或者跟上一个*号,他们返回的结果是一样的。

但如果某个字段的值存在NULL值,返回的结果可能就不一样了。比如说student表中的teacher_id字段的值有NULL的情况,那么下面这两个SQL的返回结果可能就会不一样。

SELECT COUNT(*) FROM student;
SELECT COUNT(teacher_id) FROM student;

此时,下面这两个SQL的结果是等价的:

SELECT COUNT(teacher_id) FROM student;
SELECT COUNT(teacher_id) FROM student
WHERE teacher_id IS NOT NULL;

也就是说,当COUNT后面跟上的是某个字段名,那么在计算个数时,这个字段中的NULL值是不算的。

所以前面说过,NULL值是一个很特殊的值。这一点,一定要记住。

分组汇总统计

请思考下面的查询需求:

(1)、如何获取每个班级的数学成绩平均分(因为学生太多,这里先不计算成绩在80分以下的学生),以便比较不同班级的成绩?

SELECT
class_id,avg(score)
FROM student
WHERE score > 80
GROUP BY class_id;

这里并不是要查全校所有学生的数学成绩的平均分,而是要求先按班级来分组,再计算每个班级的平均分。

这就是分组汇总统计,在SQL语言里使用GROUP BY关键字。

GROUP BY分组汇总统计按下图表示的顺序进行计算:

第一步:将源表中的数据,按GROUP BY指定的字段进行分组。值相同的记录分到一组;

第二步:各自计算所有分组的聚合函数的值;

第三步:将所有分组的计算结果合并;

(2)、如何统计股票交易表中不同的交易所的总的买入金额?

SELECT left(stock_code,2),sum(price*volume)
FROM t_stock_trans_dtl
WHERE opt_typ = '买入'
GROUP BY left(stock_code,2);

(3)、如何统计股票交易表中不同的交易所的不同交易类型的总的交易金额?

SELECT left(stock_code,2),opt_typ,sum(price*volume)
FROM t_stock_trans_dtl
GROUP BY left(stock_code,2),opt_typ;

注意:SELECT后面列出的所有字段,除了聚合函数里的字段外,其他所有的字段,都必须出现在GROUP BY的后面。

另外,如果GROUP BY后面指定的分组统计字段的值有NULL值的情况,则所有的NULL值分被分到同一个分组进行计算。

picture loss