组函数即《数据库函数》中提到的多行函数。每组记录作为整体计算,并返回一个结果,而不是每条记录返回一个结果。
常用的5个组函数:(以下expr均可以是变量、常量、数据列,无特别说明则数据类型可为任意类型)
AVG([DISTINCT|all] expr):计算多行expr的平均值,数据类型:数值型。
DISTINCT:不计算重复值;all(省略时效果相同):需要计算重复值。
COUNT(*|[DISTINCT|all]expr,[expr...]):计算多行expr的总条数
*:统计该表内的记录行数;distinct:不计算重复值。
MAX(expr)、MIN(expr):计算多行expr的最值
SUM([DISTINCT|all] expr):多行expr的总和,数据类型:数值型
Note:
- distinct 和 * 不能同时使用。
- 组函数默认把所有记录当成一组,可使用group by显示分组。
- group by当一列或多列的值完全相同时,才把这些记录当成一组。
- group by 时 null也算一组,默认升序。
- 很多数据库分组有严格规则,如果查询列表使用了组函数或select使用group by分组,则要求出现在select的字段,要么用组函数包起来,要么必须出现在group by子句中。因为组函数或group by都将导致只有一条输出,而系统无法确定输出哪条。【但MySQL没有这些规则,会输出该组的第一条记录】
分组过滤having
- having子句后是条件表达式,满足该表达式的分组才会被选出来。
- 和where子句的区别:
- where子句仅过滤行,过滤组必须用having子句;
- where子句中不能使用组函数,having才可以;
# 多行expr的平均值
SELECT
AVG(ALL `level`)
FROM
student;
#COUNT,多行expr的总条数,不考虑null
SELECT
# COUNT(*) # 表中记录条数
# COUNT(DISTINCT `level`) # level列有多少个不同的值
COUNT(DISTINCT age, `level`) # age、level不为null,且不同时相等的行数
# COUNT(DISTINCT*)# DISTINCT和*不能共用,会报异常
FROM
student;
# SUM(expr)
SELECT
# SUM(`level`) #
`level`数值列的和
# expr是常量2,所以每行值都相同
# so近似理解为行数的2倍,即n*COUNT(*)
# SUM(2)
SUM(DISTINCT 2) #每行都是2,再去重,故值为2
FROM
student;
# MAX(expr)、Min()
SELECT
MAX(id) #id列的最大值9
FROM
student;
# 统计时对null的处理
SELECT
AVG(IFNULL(`level`,0)) #不仅仅是简单的赋值,还增加了计算的列数
FROM
student;
# GROUP BY显式分组,多列参数同时相等才算一组
# null也算一组
SELECT
NAME,
# name显示的是当前组的第一个字段(与升降序无关)
sex,
`level`,
COUNT(*)
FROM
student
GROUP BY
# `level` DESC; # 降序
LEVEL,
sex;
# having过滤组
SELECT
sex,
LEVEL,
COUNT(*)
FROM
student
GROUP BY
sex # 按sex分组
HAVING
# 要求不重复level数量大于等于3的组(此处结果只有女生组)
count(DISTINCT `level`)>=3;