SQL 入门指南:聚合函数与分组查询应用

发布于:2025-09-08 ⋅ 阅读:(16) ⋅ 点赞:(0)

SQL 入门指南:聚合函数与分组查询应用

作为大学生刚接触 SQL,可能会遇到这样的需求:“算一下全班同学的平均分”“统计每个班级的人数”—— 这些需求靠基础查询很难实现,而聚合函数分组查询就是解决这类 “统计问题” 的神器。今天咱们用 “学生成绩表” 做例子,手把手教你学会这两个知识点。

我整理好了超全的学习资料,蕴含SQL、Python、Excel、数据库、数据分析等内容

学习资料汇总https://www.kdocs.cn/l/cjchDXwklk1B

一、先搞懂:什么是聚合函数?

聚合函数就是 “把一堆数据聚在一起,算出一个结果” 的函数。比如算 “全班总分”“最高分”“有多少人参考”,都要用它。SQL 里最常用的有 5 个,咱们一个个说:

聚合函数

作用

例子(算什么)

COUNT()

统计数量(非 NULL 值的个数)

全班有多少人参考

SUM()

计算总和

全班数学成绩的总分

AVG()

计算平均值

全班数学成绩的平均分

MAX()

找最大值

全班数学成绩的最高分

MIN()

找最小值

全班数学成绩的最低分

实战准备:创建 “学生成绩表”

先建一个咱们都熟悉的 “学生成绩表”(表名:student_score),后面所有例子都用它,代码可以直接复制运行:

-- 创建学生成绩表
CREATE TABLE student_score (
    学号 INT,
    姓名 VARCHAR(20),
    班级 VARCHAR(10),
    数学 INT,
    英语 INT,
    语文 INT
);

-- 插入测试数据(3个班级,6个学生)
INSERT INTO student_score 
VALUES 
(101, '张三', '1班', 85, 92, 78),
(102, '李四', '1班', 90, 88, 95),
(103, '王五', '2班', 76, 65, 82),
(104, '赵六', '2班', 88, 90, 79),
(105, '孙七', '3班', 95, 85, 92),
(106, '周八', '3班', 60, 72, 68);

运行后,表的数据长这样(可以用SELECT * FROM student_score;查看):

学号

姓名

班级

数学

英语

语文

101

张三

1 班

85

92

78

102

李四

1 班

90

88

95

103

王五

2 班

76

65

82

104

赵六

2 班

88

90

79

105

孙七

3 班

95

85

92

106

周八

3 班

60

72

68

例子 1:用聚合函数算 “全班整体统计”

比如要算:全班有多少人?数学平均分是多少?数学最高分是多少?

直接用 “聚合函数 + SELECT” 就能实现,代码如下:

-- 统计全班:人数、数学平均分、数学最高分、数学最低分、数学总分
SELECT 
    COUNT(学号) AS 全班人数,  -- 用学号统计人数(学号不会重复,更准确)
    AVG(数学) AS 数学平均分,  -- 算数学平均分
    MAX(数学) AS 数学最高分,  -- 算数学最高分
    MIN(数学) AS 数学最低分,  -- 算数学最低分
    SUM(数学) AS 数学总分     -- 算数学总分
FROM student_score;

运行结果

全班人数

数学平均分

数学最高分

数学最低分

数学总分

6

82.3333

95

60

494

这里要注意 2 个小细节:

  1. AS是给结果列起别名(比如 “数学平均分”),方便看懂;
  1. COUNT(学号)比COUNT(*)更严谨 —— 如果某行 “学号” 是 NULL,COUNT(学号)不会算它,而COUNT(*)会算(咱们例子里学号都有值,所以结果一样)。

二、再进阶:分组查询(GROUP BY)

如果想算 “每个班级的数学平均分”,而不是 “全班的”,光用聚合函数就不够了 —— 这时候需要分组查询,把数据按 “班级” 分成 3 组(1 班、2 班、3 班),再分别算每组的统计结果。

分组查询的核心语法:

SELECT 分组字段, 聚合函数 FROM 表名 GROUP BY 分组字段;

例子 2:按 “班级” 分组,算每个班的统计

比如要算:每个班级有多少人?每个班的数学平均分、语文最高分是多少?

代码如下:

-- 按班级分组,统计每个班的人数、数学平均分、语文最高分
SELECT 
    班级,  -- 分组字段(必须写在SELECT里,和GROUP BY对应)
    COUNT(学号) AS 班级人数,
    AVG(数学) AS 班级数学平均分,
    MAX(语文) AS 班级语文最高分
FROM student_score
GROUP BY 班级;  -- 按“班级”分组

运行结果

班级

班级人数

班级数学平均分

班级语文最高分

1 班

2

87.5

95

2 班

2

82

82

3 班

2

77.5

92

是不是很直观?1 班的数学平均分(87.5)明显比 3 班(77.5)高,一眼就能看出来 —— 这就是分组查询的价值。

这里有个必记规则

如果用了GROUP BY,SELECT后面只能写两种内容:①GROUP BY里的分组字段(比如 “班级”);②聚合函数(比如COUNT()、AVG())。否则会报错!

例子 3:分组后再筛选(HAVING 子句)

有时候分组后还想 “进一步筛选”,比如 “找出数学平均分超过 80 分的班级”。这时候不能用WHERE(WHERE是筛选行,在分组前生效),必须用HAVING(HAVING是筛选分组结果,在分组后生效)。

语法:

SELECT 分组字段, 聚合函数 FROM 表名 GROUP BY 分组字段 HAVING 筛选条件;

比如要 “找出数学平均分> 80 分的班级,且显示这些班级的人数和语文最高分”:

-- 先按班级分组,再筛选出“数学平均分>80”的班级
SELECT 
    班级,
    COUNT(学号) AS 班级人数,
    AVG(数学) AS 班级数学平均分,
    MAX(语文) AS 班级语文最高分
FROM student_score
GROUP BY 班级
HAVING AVG(数学) > 80;  -- 筛选分组结果:数学平均分超过80

运行结果

班级

班级人数

班级数学平均分

班级语文最高分

1 班

2

87.5

95

2 班

2

82

82

3 班的数学平均分是 77.5,没超过 80,所以被筛选掉了 —— 这就是HAVING的作用。

这里再区分一下WHERE和HAVING,避免搞混:

对比项

WHERE

HAVING

作用时机

分组筛选行

分组筛选分组结果

能否用聚合函数

不能(比如不能写WHERE AVG(数学)>80)

能(比如HAVING AVG(数学)>80)

三、总结

  1. 聚合函数:处理 “一堆数据”,返回 “一个结果”,常用 5 个:COUNT()(计数)、SUM()(求和)、AVG()(求平均)、MAX()(最大值)、MIN()(最小值);
  2. 分组查询(GROUP BY):按某个字段把数据分成多组,每组单独算聚合结果(比如 “按班级分组算平均分”);
  3. 筛选分组结果(HAVING):分组后想进一步筛选,用HAVING(不能用WHERE);
  4. 核心口诀:要分组,用GROUP BY;分组前筛行,用WHERE;分组后筛组,用HAVING。


网站公告

今日签到

点亮在社区的每一天
去签到