Skip to content
难度基础(★)
建议时长45分钟

3.7.3 分组查询

本课核心知识点整理
本课核心知识点手绘流程图(SVG)

分组查询为什么更复杂

普通查询处理的是“行级筛选与列级输出”,分组查询多了一层:先把记录按某些列分成组,再对每组做统计。字幕中特别强调,分组后的条件筛选用 HAVING,不是 WHERE

典型结构:

sql
SELECT 分组列, 聚合函数
FROM 表
WHERE 分组前的行条件
GROUP BY 分组列
HAVING 分组后的组条件
ORDER BY 排序列 ASC|DESC;

常见聚合函数

函数作用常见考法
SUM求和供应零件数量总和
AVG求平均平均成绩、平均库存
MAX最大值最高分、最大库存
MIN最小值最低分、最小库存
COUNT计数记录条数或不同对象个数

COUNT 要特别区分:

sql
COUNT(项目号)
COUNT(DISTINCT 项目号)

前者统计项目号出现的记录条数;后者统计不同项目的个数。若一个项目下有多条零件供应记录,COUNT(项目号) 可能把同一个项目算多次,而 COUNT(DISTINCT 项目号) 才是项目种类数。

WHEREHAVING

子句发生时机能否直接使用聚合函数示例
WHERE分组前通常不能WHERE 状态='有效'
GROUP BY按列形成组不涉及条件GROUP BY 供应商号
HAVING分组后可以HAVING COUNT(DISTINCT 项目号) >= 3

题干如果说“筛选选课门数大于 3 的学生”“至少供应 3 个项目的供应商”,条件依赖统计结果,应放在 HAVING

课程例子:至少供应三个项目的供应商

题干要求“查询至少供应了三个项目的供应商,输出供应商号和供应零件数总和,并按供应商号降序排序”。数据通常来自三元联系转换后的独立关系,例如:

sql
SPP(供应商号, 项目号, 零件号, 数量)

查询对象不是供应商表、项目表或零件表单独任意一个,而是记录“供应商-项目-零件”供应事实的联系表。

sql
SELECT 供应商号, SUM(数量) AS 供应零件数总和
FROM SPP
GROUP BY 供应商号
HAVING COUNT(DISTINCT 项目号) >= 3
ORDER BY 供应商号 DESC;

这里使用 COUNT(DISTINCT 项目号),因为要求的是“供应了几个不同项目”,不是供应记录条数。一个供应商可能给同一项目供应多种零件,若不用 DISTINCT 会把一个项目重复计数。

与三元联系的衔接

分组查询题可能先考 E-R 判断,再考 SQL。比如供应商、项目、零件之间是三元多对多联系,转换后形成独立联系关系 SPP。统计供应商供应项目数时,应从这个联系关系查,而不是从某个实体表查。

这类综合题的难点不是语法本身,而是先选对查询对象。

做题路线

  1. 判断是否需要聚合:出现“总数、平均、至少几个、每个部门/课程/供应商”时考虑分组。
  2. 确定分组列:题干说“按谁统计”,谁通常就是 GROUP BY
  3. 分清筛选时机:明细行条件用 WHERE,统计结果条件用 HAVING
  4. COUNT 题仔细看是记录条数还是不同对象个数,必要时用 DISTINCT
  5. 输出排序用 ORDER BY,升序 ASC 可省略,降序写 DESC

例题

单选
按“部门”统计每个部门员工人数,应使用:
单选
筛选“人数大于 10 的部门”这类分组后条件,应使用:

自查要点

  1. WHERE 和 HAVING 的区别是什么?
  2. GROUP BY 后 SELECT 中能直接出现哪些列?
  3. 常见聚合函数有哪些?