📄 一句话概括
COUNT 数行数——COUNT(*) 数所有行,COUNT(列) 只数该列有值的行;函数查询的入口篇。
📝 本节和前面几节的关系
前面都是【把行捞出来看】;从本节起连着三节学【聚合函数】——不捞行,直接在 DBMS 里算出一个数。COUNT 管个数,MAX/MIN(3-16)管极值,SUM/AVG(3-17)管总和均值。
一、聚合函数是什么
聚合(aggregate)=把一堆行压成一个数:
- 【全班多少人?】不需要把 5 行都拉回来看,让 DBMS 自己数——返回一个数字
- 1-7 的【月底分析】就是这个思路:数据不出库,结论出库
二、COUNT 的两种数法
-- 准备块(没建表先跑 3-6 的准备块)
-- ① 数所有行(*=整行,不管列里有没有空)
SELECT COUNT(*) FROM students; -- 5
-- ② 数 score 列有值的行(钱七 NULL 不算!)
SELECT COUNT(score) FROM students; -- 4
| 写法 | 数什么 | 本表结果 |
|---|---|---|
COUNT(*) |
所有行(含 NULL 行) | 5 |
COUNT(score) |
score 非 NULL 的行 | 4 |
COUNT(DISTINCT 列) |
去重后的个数 | 见下 |
-- ③ 去重计数:有几个班
SELECT COUNT(DISTINCT class) FROM students; -- 3
三、COUNT 和 WHERE 组合:条件计数
-- 80 分以上有几人(NULL 照样被条件过滤掉)
SELECT COUNT(*) FROM students WHERE score >= 80; -- 2(张三 85、李四 92)
——聚合函数前面,WHERE 照常当筛子;先筛后数。
四、动手 Demo:三个计数各跑一遍
-- ① 全班人数
SELECT COUNT(*) AS 总人数 FROM students;
-- ② 有分数的人数(对比:差的是钱七)
SELECT COUNT(score) AS 有分数人数 FROM students;
-- ③ 每个班多少人的预告(GROUP BY 在 3-18 正式讲)
SELECT COUNT(*) FROM students WHERE class = 1;
SELECT COUNT(*) FROM students WHERE class = 2;
SELECT COUNT(*) FROM students WHERE class = 3;
看到什么算成功:①是 5、②是 4——差的 1 个正是钱七;③三次查询出 2、2、1。③这种【一列三遍查】的笨办法,3-18 的 GROUP BY 一句搞定——伏笔已埋。
五、30 秒实验
对没有行的表计数:先 DELETE FROM students; 清空,再 SELECT COUNT(*) FROM students;——返回 0(不是报错也不是 NULL)。【空集的计数是 0】,这是数学和工程一致的温柔。
六、常见误区
- "COUNT(*) 和 COUNT(列) 结果一样" —— 有 NULL 列就不一样:前者数行、后者数【该列有值的行】。想知道【多少人没交卷】,恰要用这个差:
COUNT(*) - COUNT(score)。 - "COUNT 是把行拉回来自己数" —— 数数发生在 DBMS 内部,只传回一个数字;千万行的表数一下照样快(配合索引更快)。
- "COUNT 里能放表达式随便写" —— 放
COUNT(score + 5)这类没意义还易错;要么*、要么列名、要么DISTINCT 列。
自测三问(点开对答案)
1. COUNT(*) 和 COUNT(score) 在本表分别得几?差的那行是谁? **5 和 4;差的是钱七(score 为 NULL)**。 2. 聚合函数把什么变成了什么? **把一堆行压成一个数**——数据不出库、结论出库。 3. 【80 分以上几人】怎么写? **`SELECT COUNT(*) FROM students WHERE score >= 80;`**——先筛后数。- ☐ 下一节(3-16 MAX函数、MIN函数-获取记录的最大值和最小值)
相关笔记
- IN、LIKE、IS NULL-用于查询的符号2-包含值的数据、查询空数据 —— NULL 的脾气继续影响 COUNT
- 🗄️ 数据库基础 · 索引 —— 全课路线图