my+MySQL Atlas数据库学习图谱
官方手册 ↗
LEARN BY QUERYING · MYSQL 8.4

让每一条 SQL
都有清晰的答案。

让分析查询更清楚

拆解复杂步骤,计算分组排名与累计值。

示例数据查询结果动手练习
ONE DATASET, MANY QUESTIONS

准备你的练习数据 4 位客户 · 5 笔订单

+

在自己的空白练习数据库中执行。每项示例都基于初始数据独立验证;事务课程会改变数据,再次练习时请使用新的空白数据库。金额采用 DECIMAL,表使用 InnoDB。

建表与示例数据
CREATE TABLE customers (
  id INT PRIMARY KEY,
  name VARCHAR(40) NOT NULL,
  nickname VARCHAR(40) NULL
) ENGINE=InnoDB;
CREATE TABLE orders (
  id INT PRIMARY KEY,
  customer_id INT NOT NULL,
  amount DECIMAL(10,2) NOT NULL,
  status VARCHAR(20) NOT NULL,
  ordered_at DATE NOT NULL,
  FOREIGN KEY (customer_id) REFERENCES customers(id)
) ENGINE=InnoDB;
INSERT INTO customers VALUES
  (1, 'Ada', 'ada'), (2, 'Linus', NULL),
  (3, 'Grace', 'grace'), (4, 'Guido', NULL);
INSERT INTO orders VALUES
  (1, 1, 120.00, 'paid', '2026-01-02'),
  (2, 1, 80.00, 'paid', '2026-01-05'),
  (3, 2, 200.00, 'pending', '2026-01-06'),
  (4, 2, 50.00, 'paid', '2026-01-07'),
  (5, 3, 150.00, 'paid', '2026-01-09');
下载 dataset.sql ↓
THE PRACTICE

CTE 与窗口函数 03

结果基于统一数据集;计划与锁行为需结合实际环境
01MySQL 8.0 · MySQL 8.4

CTE 拆解查询步骤

先计算每个客户的已支付金额,再从这个命名结果中筛选。

常见做法写多层嵌套子查询,或建立临时表再查询。

注意事项

CTE 是语句内的命名结果,不保证物化或提速;MySQL 8.0 开始支持 WITH,不能直接用于 5.7。

官方依据 ↗核对于 2026-10-06
SQL
WITH paid_totals AS (
  SELECT customer_id, SUM(amount) AS total
  FROM orders WHERE status = 'paid'
  GROUP BY customer_id
)
SELECT customer_id, total
FROM paid_totals
WHERE total >= 150
ORDER BY customer_id;

示例结果

customer_idtotal
1200.00
3150.00

动手练习

把客户名称加入最终结果。

查看参考答案 +

在最终查询中 JOIN customers,使用 paid_totals.customer_id = customers.id。

02MySQL 8.0 · MySQL 8.4

窗口函数计算组内排名

每个客户的订单按金额排名,同时保留每一笔订单。

常见做法用相关子查询计算排名,或在应用中逐组排序。

注意事项

窗口函数不折叠行;ROW_NUMBER 的并列顺序需要额外排序键。筛选排名时用外层查询或 CTE。

官方依据 ↗核对于 2026-10-06
SQL
SELECT id, customer_id, amount,
  ROW_NUMBER() OVER (
    PARTITION BY customer_id ORDER BY amount DESC, id
  ) AS position
FROM orders
ORDER BY id;

示例结果

idcustomer_idamountposition
11120.001
2180.002
32200.001
4250.002
53150.001

动手练习

只保留每个客户金额最高的一笔订单。

查看参考答案 +

把查询放进 CTE ranked,外层 WHERE position = 1,订单为 1、3、5。

03MySQL 8.0 · MySQL 8.4

用窗口框架计算累计金额

按日期和订单 ID 排序,计算截至当前订单的累计金额。

常见做法在应用中维护累计值,或用子查询重复扫描此前的订单。

注意事项

显式写 ROWS 表达逐行累计;默认框架可能使用 RANGE,并把相同排序值视为一组。

官方依据 ↗核对于 2026-10-06
SQL
SELECT id, amount,
  SUM(amount) OVER (
    ORDER BY ordered_at, id
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) AS running_total
FROM orders
ORDER BY ordered_at, id;

示例结果

idamountrunning_total
1120.00120.00
280.00200.00
3200.00400.00
450.00450.00
5150.00600.00

动手练习

分别计算每个客户的累计订单金额。

查看参考答案 +

在 OVER 中增加 PARTITION BY customer_id,其他排序与框架保持不变。

FROM THE SOURCE

版本与官方更新

自动检查官方发布索引;中文课程由维护者核对更新。