(课堂笔记)Oracle 聚合函数与 GROUP BY 分组查询
本文总结了Oracle中聚合函数与GROUP BY分组查询的核心知识点。
主要内容包括:
1)常用聚合函数(SUM/MAX/MIN/AVG/COUNT)的使用及NULL值处理;
2)GROUP BY语法结构和分组查询示例;
3)HAVING子句与WHERE的区别;
4)SQL语句执行顺序;
5)COUNT不同写法的区别;
6)常见错误分析及综合练习。
重点强调了WHERE与HAVING的应用场景、非分组字段的使用限制以及COUNT的性能优化建议,并提供了典型例题和自测题帮助理解。
(课堂笔记)Oracle 聚合函数与GROUP BY分组查询
以下是根据你提供的课堂内容,整理出的《聚合函数与GROUP BY分组查询》复习笔记,结构清晰、便于学生复习和记忆:
📌 一、聚合函数(对多行数据进行汇总计算)
| 函数 | 作用 | 说明 |
|---|---|---|
SUM(列) | 求和 | 对数值列求和 |
MAX(列) | 最大值 | 忽略NULL |
MIN(列) | 最小值 | 忽略NULL |
AVG(列) | 平均值 | 忽略NULL |
COUNT(列) | 计数 | 忽略NULL |
COUNT(*)/COUNT(1) | 总行数 | 不忽略NULL |
✅空值(NULL)不参与聚合计算
📌 二、基础使用示例
sql
SELECT SUM(SAL) AS 总薪资, MAX(SAL) AS 最高薪资, MIN(SAL) AS 最低薪资, AVG(SAL) AS 平均薪资, COUNT(SAL) AS 员工个数 FROM EMP;
📌 三、GROUP BY 分组查询
语法结构:
sql
SELECT 分组字段, 聚合值 FROM 表 GROUP BY 分组字段;
示例:每个部门的平均薪资
sql
SELECT DEPTNO, SUM(SAL) AS 总薪资, AVG(SAL) AS 平均薪资 FROM EMP GROUP BY DEPTNO;
📌 四、HAVING 子句(对组进行过滤)
✅HAVING 用于过滤聚合值(如总数、平均值等)
✅WHERE 用于过滤行数据,不能用于聚合值
示例:只显示人数 >= 4 的部门
sql
SELECT DEPTNO, SUM(SAL) AS 总薪资, MAX(SAL) AS 最高薪资 FROM EMP GROUP BY DEPTNO HAVING COUNT(1) >= 4;
📌 五、执行顺序(非常重要)
sql
FROM -- 1. 读取表 WHERE -- 2. 行过滤(不能使用聚合) GROUP BY -- 3. 分组 HAVING -- 4. 组过滤(可以使用聚合) SELECT -- 5. 输出字段 ORDER BY -- 6. 排序⚠️非分组字段、非聚合值,不能出现在 SELECT 中
📌 六、COUNT 的区别(面试常见)
| 写法 | 说明 | 是否忽略NULL |
|---|---|---|
COUNT(1) | 常数列,统计行数 | 否 |
COUNT(*) | 统计所有行 | 否 |
COUNT(列名) | 只统计该列非NULL的行 | 是 |
✅ 性能建议:若只统计行数,推荐使用
COUNT(1)
📌 七、综合练习(含 WHERE + GROUP BY + HAVING + ORDER BY)
题目:
筛选 1981 年入职且薪资 ≥ 1000 的员工,按部门分组,
显示部门总薪资、最高薪资,
且部门统计人数 ≥ 3,结果按部门编号升序。
答案:
sql
SELECT DEPTNO, SUM(SAL) AS 总薪资, MAX(SAL) AS 最高薪资 FROM EMP WHERE TO_CHAR(HIREDATE, 'YYYY') = '1981' AND SAL >= 1000 GROUP BY DEPTNO HAVING COUNT(EMPNO) >= 3 ORDER BY DEPTNO;
📌 八、常见错误提醒
| 错误写法 | 原因 |
|---|---|
| SELECT 非分组字段 | 该字段不在 GROUP BY 中,也不是聚合值 |
| WHERE 中使用聚合函数 | WHERE 在分组前执行,无法识别聚合 |
| HAVING 中不用聚合 | 纯字段过滤应放在 WHERE 中 |
📌 九、复习自测题
sql
-- 排除 20号部门经理 和 10号文员 -- 按入职年份分组 -- 显示最高薪资、最低薪资 -- 要求该年入职人数 ≥ 2 -- 按年份升序
参考答案:
sql
SELECT TO_CHAR(HIREDATE, 'YYYY') AS YEAR, MAX(SAL) AS 最高薪资, MIN(SAL) AS 最低薪资 FROM EMP WHERE NOT (DEPTNO = 20 AND JOB = 'MANAGER' OR DEPTNO = 10 AND JOB = 'CLERK') GROUP BY TO_CHAR(HIREDATE, 'YYYY') HAVING COUNT(EMPNO) >= 2 ORDER BY YEAR;
