Skip to content

聚合函数:COUNT、SUM、AVG、MIN、MAX ​

什么是聚合函数 ​

聚合函数(Aggregate Function)对一组行进行计算,返回单个值。

示例:从第一章的 users 表开始

sql
-- 查看数据
SELECT * FROM users;

结果(5 行):

text
 id |  name   |        email        | age
----+---------+---------------------+-----
  1 | Alice   | alice@example.com   |  30
  2 | Bob     | bob@example.com     |  25
  3 | Charlie | charlie@example.com |  35
  4 | Diana   | diana@example.com   |  28
  5 | Eve     | eve@example.com     |

使用聚合函数:

sql
-- 计算总行数
SELECT COUNT(*) FROM users;

结果(1 行):

text
 count
-------
     5

聚合函数将 5 行数据合并成 1 个结果。

COUNT:计数 ​

COUNT(*) vs COUNT(column) ​

COUNT(*):计数所有行,包括 NULL

sql
SELECT COUNT(*) AS total_users FROM users;

结果:

text
 total_users
-------------
           5

COUNT(column):只计数非 NULL 的行

sql
SELECT COUNT(age) AS users_with_age FROM users;

结果:

text
 users_with_age
----------------
              4

Eve 的年龄是 NULL,所以没有被计入。

COUNT(DISTINCT column):去重计数 ​

sql
-- 创建订单表用于演示
CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    customer_name VARCHAR(50),
    product VARCHAR(50),
    amount DECIMAL(10, 2),
    order_date DATE
);

INSERT INTO orders (customer_name, product, amount, order_date) VALUES
    ('Alice', 'Laptop', 1200.00, '2026-01-15'),
    ('Bob', 'Mouse', 25.00, '2026-01-16'),
    ('Alice', 'Keyboard', 80.00, '2026-01-17'),
    ('Charlie', 'Monitor', 300.00, '2026-01-18'),
    ('Bob', 'Headphones', 50.00, '2026-01-19'),
    ('Alice', 'USB Cable', 10.00, '2026-01-20');

计数订单和客户:

sql
-- 总订单数
SELECT COUNT(*) AS total_orders FROM orders;
-- 结果:6

-- 不同客户的数量
SELECT COUNT(DISTINCT customer_name) AS unique_customers FROM orders;
-- 结果:3

SUM:求和 ​

SUM 计算数值列的总和,忽略 NULL。

sql
-- 总销售额
SELECT SUM(amount) AS total_sales FROM orders;

结果:

text
 total_sales
-------------
     1665.00

计算:1200 + 25 + 80 + 300 + 50 + 10 = 1665

SUM 忽略 NULL ​

sql
-- 假设有 NULL 值
INSERT INTO orders (customer_name, product, amount, order_date) VALUES
    ('Diana', 'Cable', NULL, '2026-01-21');

SELECT SUM(amount) AS total_sales FROM orders;

结果仍然是 1665.00(NULL 被忽略)。

SUM 与非数值列 ​

sql
-- 错误:不能对字符串求和
SELECT SUM(customer_name) FROM orders;

错误信息:

text
ERROR:  function sum(character varying) does not exist

AVG:平均值 ​

AVG 计算数值列的平均值,忽略 NULL。

sql
-- 平均订单金额
SELECT AVG(amount) AS average_order FROM orders;

结果:

text
 average_order
---------------
     277.500000

计算:1665 / 6 = 277.5

注意精度 ​

PostgreSQL 和 MySQL 返回的精度可能不同:

sql
-- 四舍五入到两位小数
SELECT ROUND(AVG(amount), 2) AS average_order FROM orders;

结果:

text
 average_order
---------------
        277.50

AVG 与 NULL ​

sql
-- 用户的平均年龄(Eve 的 NULL 被忽略)
SELECT AVG(age) AS average_age FROM users;

结果:

text
 average_age
-------------
   29.500000

计算:(30 + 25 + 35 + 28) / 4 = 29.5

如果要把 NULL 当作 0:

sql
SELECT AVG(COALESCE(age, 0)) AS average_age_with_zero FROM users;

结果:

text
 average_age_with_zero
-----------------------
            23.600000

计算:(30 + 25 + 35 + 28 + 0) / 5 = 23.6

MIN 和 MAX:最小值和最大值 ​

MIN 和 MAX 可以用于数值、字符串、日期:

数值 ​

sql
-- 最低和最高年龄
SELECT 
    MIN(age) AS youngest,
    MAX(age) AS oldest
FROM users
WHERE age IS NOT NULL;

结果:

text
 youngest | oldest
----------+--------
       25 |     35

字符串 ​

字符串按字典顺序比较:

sql
-- 第一个和最后一个客户名(字母顺序)
SELECT 
    MIN(customer_name) AS first_name,
    MAX(customer_name) AS last_name
FROM orders;

结果:

text
 first_name | last_name
------------+-----------
 Alice      | Diana

日期 ​

sql
-- 最早和最晚的订单日期
SELECT 
    MIN(order_date) AS first_order,
    MAX(order_date) AS last_order
FROM orders;

结果:

text
 first_order | last_order
-------------+------------
 2026-01-15  | 2026-01-21

组合多个聚合函数 ​

可以在一个 SELECT 中使用多个聚合函数:

sql
SELECT 
    COUNT(*) AS total_orders,
    COUNT(DISTINCT customer_name) AS unique_customers,
    SUM(amount) AS total_sales,
    AVG(amount) AS average_order,
    MIN(amount) AS smallest_order,
    MAX(amount) AS largest_order
FROM orders
WHERE amount IS NOT NULL;

结果:

text
 total_orders | unique_customers | total_sales | average_order | smallest_order | largest_order
--------------+------------------+-------------+---------------+----------------+---------------
            6 |                3 |     1665.00 |    277.500000 |          10.00 |       1200.00

聚合函数与 WHERE ​

WHERE 在聚合前过滤数据:

sql
-- 2026 年 1 月 17 日之后的订单统计
SELECT 
    COUNT(*) AS recent_orders,
    SUM(amount) AS recent_sales
FROM orders
WHERE order_date > '2026-01-17';

结果:

text
 recent_orders | recent_sales
---------------+--------------
             4 |       360.00

聚合函数的限制 ​

不能在 WHERE 中使用聚合函数 ​

sql
-- 错误:WHERE 不能用聚合函数
SELECT * FROM orders WHERE amount > AVG(amount);

错误信息:

text
ERROR:  aggregate functions are not allowed in WHERE

正确做法(使用子查询,后续章节详细讲解):

sql
SELECT * FROM orders 
WHERE amount > (SELECT AVG(amount) FROM orders WHERE amount IS NOT NULL);

不能混用聚合和非聚合列 ​

sql
-- 错误:name 是多行,COUNT(*) 是一行
SELECT name, COUNT(*) FROM users;

错误信息(PostgreSQL):

text
ERROR:  column "users.name" must appear in the GROUP BY clause or be used in an aggregate function

正确做法:要么只用聚合,要么用 GROUP BY(下一节)。

常用聚合函数速查 ​

函数作用NULL 处理
COUNT(*)计数所有行包括 NULL
COUNT(column)计数非 NULL 行忽略 NULL
COUNT(DISTINCT column)去重计数忽略 NULL
SUM(column)求和忽略 NULL
AVG(column)平均值忽略 NULL
MIN(column)最小值忽略 NULL
MAX(column)最大值忽略 NULL

练习 ​

使用 orders 表完成以下练习:

  1. 基本计数:查询 orders 表的总行数。

  2. 去重计数:查询有多少个不同的产品。

  3. 求和:计算所有订单的总金额(排除 NULL)。

  4. 平均值:计算平均订单金额,保留两位小数。

  5. 最值:查询最小和最大订单金额。

  6. 组合统计:一次查询返回:总订单数、不同客户数、总销售额、平均订单金额。

  7. 条件聚合:计算金额大于 100 的订单总数和总金额。

  8. NULL 处理:分别计算 COUNT(*) 和 COUNT(amount) 的差异(提示:插入一行 amount 为 NULL 的数据)。

完成练习后,打开本章答案页核对。

下一步 ​

学会了聚合函数。下一节学习 GROUP BY:如何按列分组,对每组分别进行聚合统计。

回到第二章概览 · 返回SQL 学习路线

用心记录每一步成长