课程 4.1 · 阅读时间:约 8 分钟
SQL 聚合函数帮助将行集转换为摘要指标:计数、求和、平均值、最小值和最大值。在本课中,您将通过 Sakila 示例学习最常见的聚合,并了解如何为每个任务选择正确的计数方法。到课程结束时,您将能够自信地在分析 SQL 中使用 COUNT、SUM、AVG、MIN 和 MAX。
SQL 中的基本聚合函数
在之前的课程中,您专注于选择单个行。现在我们进入下一个重要步骤:从数据中计算摘要值。
聚合函数在报告和分析中至关重要,因为它们可以快速回答“有多少?”、“总共多少?”和“平均值是多少?”等问题。
核心聚合函数
COUNT() - 计数行
基本语法:
COUNT(expression)
示例:
SELECT COUNT(*) AS total_payments
FROM payment;
结果:查询返回 payment 表中的行总数。
COUNT(column) 与 COUNT(*)
这两种形式看起来相似,但行为不同:
COUNT(*)计算结果集中的所有行。COUNT(column)仅计算column不为NULL的行。
如果某列包含 NULL,则 COUNT(column) 可能小于 COUNT(*)。
SELECT
COUNT(*) AS total_rentals,
COUNT(return_date) AS returned_rentals
FROM rental;
解释:total_rentals 计算所有租赁,而 returned_rentals 仅计算 return_date 被填充的行。
COUNT(DISTINCT ...) - 计数唯一值
当您需要唯一值的数量,而不仅仅是行数时,使用 COUNT(DISTINCT column)。
SELECT COUNT(DISTINCT customer_id) AS unique_customers
FROM payment;
结果:查询返回进行了支付的唯一客户数量,即使一个客户有多行支付记录。
在实践中,这对于“有多少不同的客户购买”这样的问题很重要,因为普通的 COUNT(*) 会因为重复行而过度计数。
SUM() - 计算总和
SELECT SUM(amount) AS total_amount
FROM payment;
结果:返回 amount 列的总和。
SUM(amount) 忽略 NULL。如果所有值都是 NULL,结果为 NULL。
AVG() - 计算平均值
SELECT AVG(amount) AS average_amount
FROM payment;
结果:返回非 NULL 行的平均值。
如果您希望包含 NULL 的行影响分母,请使用以下方法之一:
SELECT
AVG(amount) AS avg_ignore_null,
AVG(COALESCE(amount, 0)) AS avg_include_null_as_zero,
SUM(amount) / COUNT(*) AS avg_sum_div_all_rows
FROM payment;
MAX() - 查找最大值
SELECT MAX(amount) AS max_amount
FROM payment;
结果:返回 amount 中的最大值。
MIN() - 查找最小值
SELECT MIN(amount) AS min_amount
FROM payment;
结果:返回 amount 中的最小值。
MIN() 和 MAX() 都会忽略 NULL。如果所有值都是 NULL,它们会返回 NULL。
MIN(column) 与 ORDER BY ... LIMIT 1
它们并不总是等价的。
SELECT MIN(column_name)
FROM table_name;
SELECT column_name
FROM table_name
ORDER BY column_name
LIMIT 1;
MIN(column_name)查找非NULL值中的最小值。ORDER BY ... LIMIT 1返回排序后的第一行。- 如果您的 DBMS 将
NULL排在前面,则第二个查询可能返回NULL,而MIN()仍然返回最小的非NULL值。
MIN() 的可靠等价物:
SELECT column_name
FROM table_name
WHERE column_name IS NOT NULL
ORDER BY column_name
LIMIT 1;
实际用法
计数客户
SELECT COUNT(*) AS total_customers
FROM customer;
按员工计算总销售额
SELECT
staff_id,
SUM(amount) AS staff_total
FROM payment
GROUP BY staff_id;
按客户计算平均支付
SELECT
customer_id,
AVG(amount) AS avg_payment
FROM payment
GROUP BY customer_id;
计数唯一支付客户
SELECT COUNT(DISTINCT customer_id) AS paying_customers
FROM payment;
常见问题解答
COUNT(*) 和 COUNT(column) 之间有什么区别?
COUNT(*) 计算所有结果行。COUNT(column) 仅计算指定列不为 NULL 的行。
何时应使用 COUNT(DISTINCT ...)?
当您需要唯一值的数量而不是总行数时使用,例如唯一客户而不是总支付。
为什么 AVG 可能返回意外值?
因为 AVG(column) 忽略 NULL。如果您希望这些行影响分母,请使用 COALESCE 或将 SUM(column) 除以 COUNT(*)。
面试问题
SQL 中的聚合函数是什么?
它们是计算多行摘要的函数,例如计数(COUNT)、求和(SUM)或平均值(AVG)。它们每组或整个结果集返回一个值。
COUNT(*)、COUNT(column) 和 COUNT(DISTINCT column) 之间有什么区别?
COUNT(*) 计算所有行,COUNT(column) 计算该列中的非 NULL 值,COUNT(DISTINCT column) 计算唯一的非 NULL 值。
MIN 和 ORDER BY ... LIMIT 1 如何返回不同的结果?
如果某列包含 NULL 且 DBMS 将 NULL 排在前面,ORDER BY ... LIMIT 1 可能返回 NULL,而 MIN() 返回最小的非 NULL 值。
本课的关键要点:
- 聚合函数快速提供摘要指标。
COUNT(*)、COUNT(column)和COUNT(DISTINCT ...)解决不同的计数任务。SUM、AVG、MIN和MAX通常忽略NULL,这会影响分析。- 当您需要唯一实体而不是行总数时,
COUNT(DISTINCT ...)是必不可少的。 - 正确处理
NULL直接影响报告的准确性。
在下一课中,我们将学习 GROUP BY 并了解如何按类别构建聚合。