SQL GROUP BY 分组统计
SQL GROUP BY 分组 · 难度:进阶 · +15XP
SQL GROUP BY 分组
GROUP BY将数据按某个(或多个)列的值分组,然后对每个组应用聚合函数。它是"按类别统计"的核心工具,比如按城市统计人数、按部门统计平均薪资。
基本语法
SELECT 分组列, 聚合函数(值列)
FROM 表名
WHERE 条件 -- 分组前过滤
GROUP BY 分组列
HAVING 条件 -- 分组后过滤
ORDER BY 排序列;
分组示例
-- 按城市统计学生人数和平均分
SELECT
city AS 城市,
COUNT(*) AS 人数,
AVG(score) AS 平均分
FROM students
GROUP BY city
ORDER BY 人数 DESC;
WHERE vs HAVING
| WHERE | HAVING |
|---|---|
| 分组前过滤行 | 分组后过滤组 |
| 不能用聚合函数 | 必须用聚合函数 |
WHERE score > 60 | HAVING AVG(score) > 75 |
| 执行顺序:先WHERE → 再GROUP BY → 最后HAVING |
-- WHERE 先过滤掉不及格的学生,再分组统计
SELECT city, COUNT(*) AS cnt, AVG(score) AS avg_score
FROM students
WHERE score >= 60 -- 先过滤
GROUP BY city
HAVING cnt >= 3 -- 只显示人数≥3的城市
ORDER BY avg_score DESC;
多列分组
-- 按城市和年龄分组(分组粒度更细)
SELECT city, age, COUNT(*) AS num
FROM students
GROUP BY city, age;
-- 分组后使用聚合函数
SELECT
YEAR(enroll_date) AS 入学年份,
COUNT(*) AS 人数,
SUM(score) AS 总分
FROM students
GROUP BY YEAR(enroll_date);
实战练习
- 按城市统计学生人数,按人数从多到少排列
- 统计每个城市的最高分和最低分
- 找出平均分超过75分的城市(用HAVING)
- 按年级分组统计各年级的学生数量和平均成绩
GROUP BY 使用要点
-- 常见错误:SELECT中出现了非分组列且非聚合列
SELECT city, name, AVG(score) FROM students GROUP BY city;
-- GROUP BY 配合 CASE WHEN 做分段统计
SELECT
CASE WHEN score >= 90 THEN '优秀'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END AS 等级,
COUNT(*) AS 人数
FROM students GROUP BY 等级;
掌握GROUP BY是进行数据分析的关键技能。几乎所有统计报表都需要用到分组查询。