0Pricing
Coding Interview Prep · 课时

包含 NULL 的 SUM 和 AVG

了解 AVG 为什么忽略 NULL,以及这会如何影响面试官期待的答案

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

AVG 中隐藏的陷阱

这是一个经典的面试问题,常常会让粗心的候选人失分:“假设有一个 salary 列,其中包含一些 NULL。AVG(salary) 会计算什么?这是否符合业务需求?”

诚实而准确的回答可以看出您是否理解聚合函数会忽略 NULL,而这会改变平均值的分母。如果在生产环境中弄错这一点,报告中的平均值可能会在不知不觉中偏高。

让我们把这种行为讲清楚。

示例数据

在整节课中使用这张 employees 表,其中包含可为 NULL 的 bonus 列:

  • Alice,奖金 100
  • Bob,奖金 200
  • Carol,奖金 NULL
  • Dan,奖金 300

共有四行,其中三行的奖金不为 NULL,一行为 NULL。我们将对这些数据执行 SUM 和 AVG,并观察 NULL 的处理方式。

SUM 忽略 NULL

SUM(bonus) 只会将不为 NULL 的值相加:100 + 200 + 300 = 600。NULL 所在的行不会产生任何贡献;它只是被跳过,而不是作为会影响计数的 0 参与计算。

实际效果就像 NULL 表示缺少值一样。SUM 遇到 NULL 不会报错,并且只有在所有输入都为 NULL 时才会返回 NULL。

SELECT SUM(bonus) AS total_bonus
FROM employees;
-- returns 600

AVG 同样忽略 NULL

AVG(bonus) 是关键所在。它计算的是不为 NULL 的值之和除以不为 NULL 的值的数量:600 / 3 = 200。

分母是 3,而不是 4。NULL 所在的行既不会计入分子,也不会计入除数。这正是 AVG 可能令人意外的原因:它计算的是现有值的平均值,而不是所有行的平均值。

SELECT AVG(bonus) AS avg_bonus
FROM employees;
-- 600 / 3 = 200, NOT 600 / 4 = 150

分母为何重要

假设在业务上,NULL 奖金表示“没有获得奖金”,也就是 0。那么业务上正确的平均值应为 600 / 4 = 150,但 AVG(bonus) 报告的是200。

面试中的正确回答是:“AVG 会忽略 NULL,因此它计算的是有奖金员工的平均值。如果 NULL 表示 0,我就必须先将 NULL 转换为 0。”能够说清这种差异,正是获得这一分的关键。

使用 COALESCE 将 NULL 转为 0

如果要将 NULL 当作 0,并计算所有行的平均值,请将列包装在 COALESCE(bonus, 0) 中。这样每一行都有数值,分母就会变为 4。

结果为 600 / 4 = 150。要点是:AVG(col) 和 AVG(COALESCE(col, 0)) 回答的是不同的业务问题。请有意识地进行选择。

SELECT AVG(COALESCE(bonus, 0)) AS avg_over_all
FROM employees;
-- 600 / 4 = 150

AVG = SUM / COUNT:请谨慎

一个有用的等式是:AVG(col) 等于 SUM(col) / COUNT(col) — 请注意是 COUNT(col),而不是 COUNT(*),因为 AVG 和这个 COUNT 都会跳过 NULL。

如果错误地写成 SUM(col) / COUNT(*),得到的就是所有行的平均值(这里是 150),与 AVG 的结果(200)不同。面试官有时会要求您手动还原 AVG,以确认您选择了正确的 COUNT。

SELECT
  AVG(bonus)                       AS builtin_avg,   -- 200
  SUM(bonus) * 1.0 / COUNT(bonus)  AS manual_avg,    -- 200
  SUM(bonus) * 1.0 / COUNT(*)      AS over_all_rows  -- 150
FROM employees;

整数除法陷阱

手动计算平均值时有一个隐蔽的错误:在许多数据库中,两个整数相除会执行整数除法,从而截断小数部分。7 / 2 可能得到 3,而不是 3.5。

AVG 通常会返回小数,但如果您使用整数列通过 SUM / COUNT 重新计算,就可能丢失精度。请先乘以 1.0,或先将其转换为小数类型。

SELECT
  SUM(bonus) / COUNT(bonus)        AS maybe_truncated,
  SUM(bonus) * 1.0 / COUNT(bonus)  AS precise
FROM employees;

所有值都为 NULL 时

这是面试官喜欢考查的边界情况:如果所有值都为 NULL,或者筛选条件没有匹配任何行,会怎样?

  • 当没有不为 NULL 的输入时,SUM 会返回 NULL(而不是 0)。
  • AVG 也会返回 NULL,因为除以 0 个值没有定义。
  • 相比之下,COUNT 会返回 0。

如果需要数值默认值,请将结果包装在 COALESCE(SUM(col), 0) 中。

SELECT COALESCE(SUM(bonus), 0) AS safe_total
FROM employees
WHERE 1 = 0;  -- no rows: returns 0, not NULL

按组计算平均值

同样的 NULL 规则也适用于 GROUP BY。每个组的 AVG 都会除以该组中不为 NULL 的值的数量。如果某个组的奖金全部为 NULL,那么该组的 AVG 就会得到 NULL。

因此,当您看到出乎意料的按部门统计的平均值时,应先怀疑 NULL 使各组的分母变小,而不是先怀疑连接错误。

SELECT department, AVG(bonus) AS avg_bonus
FROM employees
GROUP BY department;

如何表述这个答案

一个经过完善的面试回答可以这样说:“SUM 和 AVG 都会忽略 NULL。AVG 除以不为 NULL 的值的数量,因此 NULL 实际上会使分母变小。如果 NULL 应当计为 0,我会在聚合之前使用 COALESCE 将其转换为 0;否则,平均值只反映那些有值的行。”

这一句话同时体现了正确性、业务理解和解决方法。

快速检查

将这条规则应用到示例数据上。

小结

SUM 和 AVG 处理 NULL 时的要点:

  • 两者都会完全忽略 NULL。
  • AVG(col) = SUM(col) / COUNT(col) — 分母不包含 NULL。
  • 当 NULL 表示 0 且应当参与计算时,请使用 COALESCE(col, 0)。
  • 全部为 NULL 或没有行的输入会使 SUM 和 AVG 返回 NULL(COUNT 返回 0)。
  • 手动重新计算 AVG 时,请注意整数除法。

下一部分:MIN、MAX 以及对非数值数据进行聚合。

常见问题解答

「包含 NULL 的 SUM 和 AVG」课时是免费的吗?

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

「包含 NULL 的 SUM 和 AVG」这节课中我会学到什么?

了解 AVG 为什么忽略 NULL,以及这会如何影响面试官期待的答案 你通过在浏览器中直接运行的动手代码来练习 Coding Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

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

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

「包含 NULL 的 SUM 和 AVG」课时需要多长时间?

大多数 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