0Pricing
Coding Interview Prep · 课时

COUNT(*)、COUNT(column) 与 COUNT(DISTINCT)

掌握经典问题:每种 COUNT 写法如何处理 NULL 和重复值

COUNT(*)、COUNT(column) 与 COUNT(DISTINCT) 是 CoddyKit 上的免费 Coding Interview Prep 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Coding Interview Prep 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Coding Interview Prep 课程共包含 4 节课。

您将被问到的问题

如果您参加 SQL 面试,请准备好在前十分钟内回答这个问题:COUNT(*)、COUNT(column) 和 COUNT(DISTINCT column) 有什么区别?

这个问题看似简单,但面试官会借此检查您是否真正理解聚合函数如何处理 NULL 值和重复值。回答自信而准确,说明您编写过实际查询,而不只是记住了语法。

在本课中,我们将建立一个非常扎实的思维模型,让您能够立即回答,并解释其中的原因。

COUNT(*) 统计行数

COUNT(*) 统计行。它完全不会查看任何列值,因此 NULL 与它无关。如果表中有 100 行,COUNT(*) 就返回 100,仅此而已。

这里的星号不是用于乘法,也不是用于展开列。它是一个特殊标记,表示“统计每一行符合条件的行”。当问题只是“有多少条记录?”时,您应当使用这种形式。

SELECT COUNT(*) AS total_rows
FROM employees;

用于分析的示例数据

让我们用一张小表来说明所有内容。假设有一张 employees 表,其中包含可为 NULL 的 department 列:

  • Alice,销售
  • Bob,销售
  • Carol,NULL
  • Dan,工程
  • Eve,NULL

总共有5 行。其中三行有部门值(销售、销售、工程),两行的值为 NULL。请记住这些数字;接下来我们会用三种不同方式统计这张表。

COUNT(column) 跳过 NULL

COUNT(column) 只统计该列不为 NULL 的行。它会完全忽略 NULL 值。

在我们的示例数据中,COUNT(department) 返回3,而不是 5,因为有两个部门值为 NULL。这是整节课中最重要的事实:对列使用 COUNT 时,永远不会统计 NULL。

SELECT COUNT(department) AS depts_present
FROM employees;
-- returns 3 on our sample data

目前的两者对比

在同一张包含 5 行的表中并列比较:

  • COUNT(*) = 5(每一行)
  • COUNT(department) = 3(不为 NULL 的部门)

两者相差 5 减去 3,也就是 NULL 部门的数量。一个实用的面试技巧是:COUNT(*) - COUNT(col) 可以直接得到该列中 NULL 的数量,而无需单独编写 WHERE 子句。

SELECT COUNT(*) - COUNT(department) AS null_departments
FROM employees;
-- returns 2

COUNT(DISTINCT 列)

COUNT(DISTINCT column) 统计不重复且不为 NULL 的值的数量。它会先去除重复值,再忽略 NULL,最后统计剩余值。

在我们的数据中,不重复的部门值是销售和工程,因此 COUNT(DISTINCT department) 返回2。两个 NULL 不会被统计,重复的销售也会合并为一个。

SELECT COUNT(DISTINCT department) AS unique_depts
FROM employees;
-- returns 2

三者放在一起

这张包含 5 行的表的完整结果如下:

  • COUNT(*) = 5 — 行
  • COUNT(department) = 3 — 不为 NULL 的值
  • COUNT(DISTINCT department) = 2 — 不重复且不为 NULL 的值

如果您能记住这个顺序:先处理 NULL,再处理重复值,那么就掌握了整个概念。请注意,每种形式返回的值都小于或等于它上方的形式。

SELECT
  COUNT(*)                       AS rows_total,
  COUNT(department)              AS depts_present,
  COUNT(DISTINCT department)     AS unique_depts
FROM employees;

一道完整的面试变体题

面试官经常会将问题换一种说法:“有多少名员工被分配到了部门?一共有多少个不同的部门?”

前半问对应 COUNT(department)(已分配意味着不为 NULL)。后半问对应 COUNT(DISTINCT department)。能够识别每种表述对应哪个 COUNT,正是这道题要考查的技能。

SELECT
  COUNT(department)          AS assigned_employees,
  COUNT(DISTINCT department) AS distinct_departments
FROM employees;

带条件的 COUNT

一个常见的追问是:只统计满足某个条件的行。一种简洁且具有良好可移植性的技巧,是对 CASE 表达式使用 COUNT。由于 COUNT(column) 会跳过 NULL,因此可以让 CASE 对要排除的行返回 NULL。

这里我们统计销售部门的员工。CASE 只对销售行产生值,对其他行返回 NULL,因此 COUNT 只会统计这些行。

SELECT
  COUNT(CASE WHEN department = 'Sales' THEN 1 END) AS sales_count
FROM employees;
-- returns 2

需要避免的常见错误

请注意面试官可能设置的这些陷阱:

  • 认为 COUNT(column) 等于 COUNT(*) — 只有当该列完全没有 NULL 时,两者才相等。
  • 认为 COUNT(DISTINCT col) 会将 NULL 作为一个不重复值包含在内 — 实际上不会。
  • 编写 COUNT(1) 并以为它会跳过 NULL — 它的行为与 COUNT(*) 一样,会统计所有行。

在面试中主动说明这些情况,可以展示您的理解深度。

COUNT(1) 与 COUNT(常量)

候选人经常会问,COUNT(*) 和 COUNT(1) 哪个更快。答案是:它们在语义上完全相同 — 无论是否存在 NULL,两者都会统计每一行;现代优化器也会以相同方式处理它们,因此没有实际的性能差异。

COUNT(1) 中的常量永远不会是 NULL,因此不会跳过任何行。为了清晰起见,建议使用 COUNT(*);这是更惯用的写法。

SELECT COUNT(*) AS a, COUNT(1) AS b
FROM employees;
-- a and b are always equal

快速检查

在示例表上检验您的思维模型。

小结

现在您已经掌握了最常被问到的聚合问题:

  • COUNT(*) 统计每一行,包括 NULL。
  • COUNT(column) 只统计不为 NULL 的值。
  • COUNT(DISTINCT column) 统计不重复且不为 NULL 的值。
  • COUNT(*) - COUNT(col) 可以直接得到 NULL 的数量。
  • COUNT(1) 等于 COUNT(*) — 不会跳过 NULL,也没有速度差异。

请清晰地说出结论,并说明背后的原因。接下来:SUM 和 AVG 如何处理 NULL。

常见问题解答

「COUNT(*)、COUNT(column) 与 COUNT(DISTINCT)」课时是免费的吗?

是的 — 「COUNT(*)、COUNT(column) 与 COUNT(DISTINCT)」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Coding Interview Prep 课程的其余内容,请升级到 CoddyKit PRO。 Coding Interview Prep 课程共包含 4 节课。

「COUNT(*)、COUNT(column) 与 COUNT(DISTINCT)」这节课中我会学到什么?

掌握经典问题:每种 COUNT 写法如何处理 NULL 和重复值 你通过在浏览器中直接运行的动手代码来练习 Coding Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Coding Interview Prep 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Coding Interview Prep 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「COUNT(*)、COUNT(column) 与 COUNT(DISTINCT)」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Coding Interview Prep 课中编写并运行代码吗?

能。每节 Coding Interview Prep 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. COUNT(*)、COUNT(column) 与 COUNT(DISTINCT)
  2. 包含 NULL 的 SUM 和 AVG
  3. MIN、MAX 与非数值汇总
  4. 不使用 GROUP BY 的汇总
← 返回 Coding Interview Prep