惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
博客园_首页
IT之家
IT之家
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
大猫的无限游戏
大猫的无限游戏
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 司徒正美
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
Jina AI
Jina AI
月光博客
月光博客
小众软件
小众软件
S
SegmentFault 最新的问题
量子位
阮一峰的网络日志
阮一峰的网络日志
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

博客园 - lzhdim

25个每个开发人员都应该掌握的JavaScript 数组方法 20260831 - 个人小作品更新 C#使用SQLite数据库例子 - 开源研究系列文章 20260830 - 个人小作品更新 20260829 - 个人小作品更新 13、JavaScript事件循环机制 - JavaScript学习系列文章 首款媲美分体水冷的一体水冷!微星CORELIQUID E15 360水冷散热器评测:目前为止 锐龙9 9950X3D最强性能释放 JavaScript常见的内存泄露问题 - JavaScript学习系列文章 C#开发的颜色取色器 - 开源研究系列文章 - 个人小作品 成长环境 - 我的闪存 提高 SQL 语句执行速度的方法 JavaScript安全最佳实践 关闭iPhone一些默认设置,让iPhone更流畅 20260814 - 个人小作品更新 JavaScript对象与元编程 20260812 - 个人小作品更新 JavaScript 模块化系统 Markdown 语法完全指南 C# 通过 Windows API 实现进程内存读写操作 JavaScript 函数进阶课题 C#开发的基于钩子技术监测键鼠事件的例子 - 开源项目研究文章 JavaScript异步编程的演进 近十年最帅风冷!酷冷至尊V8 ACE 3DHP散热器评测:单塔能干翻双塔 20260723 - 个人小作品更新 C# 中读取CPU、硬盘和内存温度 雷柏VT3s MAX鼠标评测:中小手型用户也没有被遗忘 顶尖性能的小号电竞鼠标来了 JavaScript 中的原型与继承 1分钟查清局域网所有IP 20260714 - 个人小作品更新 WorkBuddy 完整教程手册
SQL 入门 7:SQL 聚合与分组:函数、GROUP BY 与 ROLLUP
lzhdim · 2026-03-26 · via 博客园 - lzhdim

以下为 SQL 中聚合函数、分组查询及汇总的用法解析。需要相关数据可私信。

学习内容

  1. 聚合函数
    • COUNT():统计行数,忽略空值;COUNT(*) 计数所有行。
    • SUM():计算总和。
    • AVG():求平均值。
    • MAX():返回最大值。
    • MIN():返回最小值。
    • GROUP_CONCAT():合并多行为字符串。
    • 处理列数据,返回单一结果。
    • 常见函数:
    • 支持表达式(如 SUM(invoice_total * 1.4)),可用于日期。
    • DISTINCT 去除重复值。
  2. GROUP BY 子句
    • 按指定列分组,结合聚合函数计算每组结果。
    • 顺序:SELECT → FROM → WHERE → GROUP BY → ORDER BY。
    • 多列分组用逗号分隔,无需括号。
  3. HAVING 子句
    • 过滤分组后的结果,解决 WHERE 无法处理聚合值的问题。
    • 置于 GROUP BY 后,支持多条件。
  4. WITH ROLLUP
    • 在 GROUP BY 后添加,生成分组汇总行。
    • 多列分组时,逐级汇总至总计。

示例代码与讲解

1. 聚合函数

SELECT MAX(invoice_total)
FROM invoices;

  • 返回 invoice_total 最大值。

SELECT
    MAX(invoice_total) AS highest,
    MIN(invoice_total) AS lowest,
    AVG(invoice_total) AS AVG,
    SUM(invoice_total * 1.4) AS SUM,
    COUNT(invoice_total) AS COUNT
FROM invoices;

  • 多聚合查询,含表达式,重命名结果为五列。

SELECT
    MAX(payment_date) AS highest,
    MIN(payment_date) AS lowest,
    COUNT(payment_date) AS COUNT
FROM invoices;

  • 应用于日期,COUNT 不计空值。

SELECT COUNT(*) AS number_invoices
FROM invoices;

  • 统计所有行,含空值。

SELECT
    MAX(payment_date) AS highest,
    MIN(payment_date) AS lowest,
    COUNT(payment_date) AS COUNT
FROM invoices
WHERE payment_date >= '2018-01-01';

  • 筛选后聚合。

SELECT COUNT(DISTINCT client_id) AS number_client
FROM invoices;

  • 统计唯一 client_id,避免重复计数。

2. GROUP BY

SELECT client_id, SUM(invoice_total) AS Total_sales
FROM invoices
GROUP BY client_id;

  • 按 client_id 分组,计算每组销售总额。

SELECT client_id, SUM(invoice_total) AS Total_sales
FROM invoices
WHERE invoice_date >= '2019-07-01'
GROUP BY client_id
ORDER BY Total_sales DESC;

  • 筛选后分组,按总额降序。

SELECT c.city, c.state, SUM(i.invoice_total) AS Total_sales
FROM invoices i
JOIN clients c USING (client_id)
GROUP BY c.state, c.city;

  • 连接表后,按州和城市分组,逗号分隔条件。

3. HAVING

SELECT client_id, SUM(invoice_total) AS Total_sales
FROM invoices
GROUP BY client_id
HAVING Total_sales >= 800;

  • 筛选销售总额 ≥ 800 的组。

SELECT client_id, SUM(invoice_total) AS Total_sales, COUNT(*) AS number_invoices
FROM invoices
GROUP BY client_id
HAVING Total_sales >= 800 AND number_invoices > 5;

  • 多条件筛选:总额 ≥ 800 且发票数 > 5。

4. WITH ROLLUP

SELECT client_id, SUM(invoice_total) AS Total_sales
FROM invoices
GROUP BY client_id WITH ROLLUP;

  • 添加汇总行,显示所有 client_id 的总计。

SELECT state, city, SUM(invoice_total) AS Total_sales
FROM invoices
JOIN clients c USING (client_id)
GROUP BY state, city WITH ROLLUP;

  • 按州和城市分组,逐级汇总至总计。

作业

1. 聚合与 UNION

SELECT
    'First half of 2019' AS date_range,
    SUM(invoice_total) AS Total_sales,
    SUM(payment_total) AS Total_payments,
    SUM(invoice_total) - SUM(payment_total) AS what_we_expect
FROM invoices
WHERE invoice_date BETWEEN '2019-01-01' AND '2019-06-30'
UNION
SELECT
    'Second half of 2019' AS date_range,
    SUM(invoice_total) AS Total_sales,
    SUM(payment_total) AS Total_payments,
    SUM(invoice_total) - SUM(payment_total) AS what_we_expect
FROM invoices
WHERE invoice_date BETWEEN '2019-07-01' AND '2019-12-31'
UNION
SELECT
    'Total' AS date_range,
    SUM(invoice_total) AS Total_sales,
    SUM(payment_total) AS Total_payments,
    SUM(invoice_total) - SUM(payment_total) AS what_we_expect
FROM invoices
WHERE invoice_date BETWEEN '2019-01-01' AND '2019-12-31';

  • 计算 2019 年上下半年及全年的销售、付款和预期差额。

2. 分组查询

SELECT date, pm.name AS payment_method, SUM(amount) AS Total_payments
FROM payments p
JOIN payment_methods pm ON p.payment_method = pm.payment_method_id
GROUP BY date, pm.name
ORDER BY date;

  • 按日期和支付方式分组,计算付款总额。

3. HAVING 筛选

USE sql_store;
SELECT c.customer_id, SUM(oi.quantity * oi.unit_price) AS total_buy
FROM customers c
JOIN orders o USING (customer_id)
JOIN order_items oi USING (order_id)
WHERE c.state = 'VA'
GROUP BY c.customer_id
HAVING total_buy >= 100;

  • 查询 VA 州客户总购买额,筛选 ≥ 100 的结果。

4. ROLLUP 汇总

USE sql_invoicing;
SELECT pm.name, SUM(p.amount) AS SUM
FROM payments p
JOIN payment_methods pm ON p.payment_method = pm.payment_method_id
GROUP BY pm.name WITH ROLLUP;

  • 按支付方式分组,含总计。

总结

本次解析了聚合函数(COUNT、SUM 等)、GROUP BY 分组、HAVING 过滤及 ROLLUP 汇总。基于 sql_invoicing 和 sql_store 数据库。