顺序
| 书写顺序 | 执行顺序 | 核心说明 |
|---|
| 1. SELECT | 6. SELECT | 筛选返回字段、执行字段计算或定义别名 |
| 2. FROM | 1. FROM/JOIN | 确定查询基础表,执行表关联操作(内连接、左连接等) |
| 3. WHERE | 2. WHERE | 过滤原始表数据,不能使用聚合函数 |
| 4. GROUP BY | 3. GROUP BY | 将 WHERE 过滤后的数据按指定字段分组 |
| 5. HAVING | 5. HAVING | 过滤分组后的聚合结果,可使用聚合函数 |
| 6. ORDER BY | 8. ORDER BY | 对最终结果排序,可使用 SELECT 定义的别名 |
| 7. LIMIT/OFFSET | 9. LIMIT/OFFSET | 截取排序后的结果集,限制返回行数 |
| - | 4. 聚合函数计算 | 紧跟 GROUP BY,执行 SUM/COUNT/AVG 等统计计算 |
| - | 7. DISTINCT | 对 SELECT 筛选后的结果进行去重处理 |
关键速记要点
- 执行核心逻辑:先确定数据源(FROM/JOIN)→ 过滤原始数据(WHERE)→ 分组(GROUP BY)→ 聚合计算 → 过滤分组结果(HAVING)→ 筛选字段(SELECT)→ 去重(DISTINCT)→ 排序(ORDER BY)→ 截取结果(LIMIT)
- WHERE vs HAVING:WHERE 管 “分组前”,不能用聚合函数;HAVING 管 “分组后”,可以用聚合函数
- 别名使用:ORDER BY 可以用 SELECT 定义的字段别名,因为它执行在 SELECT 之后
示例
1. 先创建测试表并插入数据
我们以电商订单表为例,包含商品分类、订单金额、下单时间等字段,贴合实际业务场景
-- 创建订单表 CREATE TABLE t_order ( order_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '订单ID', user_id INT NOT NULL COMMENT '用户ID', product_category VARCHAR(50) NOT NULL COMMENT '商品分类', order_amount DECIMAL(10,2) NOT NULL COMMENT '订单金额', order_time DATETIME NOT NULL COMMENT '下单时间' ) COMMENT '电商订单表'; -- 插入测试数据 INSERT INTO t_order (user_id, product_category, order_amount, order_time) VALUES (101, '电子产品', 3999.00, '2025-01-10 14:30:00'), (102, '电子产品', 2999.00, '2025-01-15 10:20:00'), (103, '服装鞋帽', 299.00, '2025-01-12 09:15:00'), (104, '服装鞋帽', 599.00, '2025-01-18 16:40:00'), (105, '食品生鲜', 89.00, '2025-01-20 11:00:00'), (106, '电子产品', 1999.00, '2025-01-22 15:30:00'), (107, '服装鞋帽', 199.00, '2025-01-25 08:20:00'), (108, '食品生鲜', 129.00, '2025-01-28 19:10:00');
2. 完整查询 SQL(含分组、聚合、排序)
需求:统计 2025 年 1 月各商品分类的订单总金额、订单数量,筛选出总金额大于 1000 的分类,按总金额降序排序
SELECT product_category AS 商品分类, SUM(order_amount) AS 分类总金额, COUNT(order_id) AS 订单数量 FROM t_order WHERE order_time BETWEEN '2025-01-01 00:00:00' AND '2025-01-31 23:59:59' GROUP BY product_category HAVING SUM(order_amount) > 1000 ORDER BY 分类总金额 DESC;
3. 分步执行结果解析
| 执行步骤 | 对应子句 | 执行结果说明 |
|---|
| 1 | FROM t_order | 确定数据源为订单表,获取 8 条原始订单数据 |
| 2 | WHERE order_time BETWEEN... | 过滤出 2025 年 1 月的订单,仍为 8 条(测试数据均符合) |
| 3 | GROUP BY product_category | 按商品分类分组,得到 3 个分组:电子产品、服装鞋帽、食品生鲜 |
| 4 | 聚合函数计算(SUM/COUNT) | 计算每个分组的总金额和订单数:电子产品:3999+2999+1999=8997,共 3 单服装鞋帽:299+599+199=1097,共 3 单食品生鲜:89+129=218,共 2 单 |
| 5 | HAVING SUM(order_amount) > 1000 | 过滤掉总金额≤1000 的分组,保留电子产品、服装鞋帽2 个分组 |
| 6 | SELECT | 筛选并返回商品分类、总金额、订单数量 3 个字段,应用别名 |
| 7 | ORDER BY 分类总金额 DESC | 按总金额降序排序,最终结果顺序:电子产品 → 服装鞋帽 |
4. 最终查询结果
| 商品分类 | 分类总金额 | 订单数量 |
|---|
| 电子产品 | 8997.00 | 3 |
| 服装鞋帽 | 1097.00 | 3 |