9、GROUP BY 对结果集的行进行分组、HAVING 子句 分组后过滤

1、GROUP BY

是 SELECT 语句的一个可选子句。GROUP BY 子句允许您根据一个或多个列的值对行进行分组

  • 按照指定列的值将表中的行分组,每个不同的行值形成一个组,相同值的行被合并到同一组中。
  • 把该列中「值相同的行」全部合并成「一行」;而「值不同的行」各自成为独立的一组(也是一行)。
  • 通常与聚合函数(如 COUNT()、SUM()、AVG()、MAX()、MIN() 等)一起使用,以便对每个分组执行计算。
  • 与 HAVING 子句配合使用,WHERE 用于过滤分组前的行,而 HAVING 用于过滤分组后的结果。

语法:

SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 字段名 [ HAVING 分组后的过滤条件 ];   
-- 在 SELECT 子句中的所有非聚合列(没有使用聚合函数的列)都必须出现在 GROUP BY 子句中。

例:

-- ✅ 正确
SELECT dept, COUNT(*) 
FROM employees 
GROUP BY dept;

-- ❌ 错误(name 不是聚合列,没有出现在 GROUP BY 中,)
SELECT dept, name, COUNT(*) 
FROM employees 
GROUP BY dept;

假设有一个订单表 orders

order_idcustomer_idproductamount
1 101 Laptop 1200
2 102 Mouse 25
3 101 Keyboard 75
4 103 Monitor 300
5 102 Laptop 1100

执行语句:

-- 统计每位客户的订单总金额
SELECT customer_id, SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id;

结果:

customer_idtotal_amount
101 1275
102 1125
103 300

 

--product(产品)分组,统计每个产品出现了多少次(即销售次数)。
SELECT product, COUNT(*) AS sales_count
FROM orders
GROUP BY product;

结果:

productsales_count
Laptop 2
Mouse 1
Keyboard 1
Monitor 1

 核心规则

当SELECT子句的列表中包含聚合函数(如COUNT, SUM, AVG, MAX, MIN)时:

  1. 必须使用 GROUP BY子句,所有在SELECT中出现的非聚合列,都必须出现在GROUP BY子句中。

  2. GROUP BY子句中可以包含SELECT中没有出现的非聚合列

  3. SELECT中可以只包含聚合列,不包含任何非聚合列

否则,数据库无法确定“该返回哪一行的值”,结果具有不确定性,因此报错(如 MySQL Error 1140)。

2、HAVING 子句

用于对 GROUP BY 分组后的结果进行过滤可以使用聚合函数(如 COUNT()SUM()AVG() 等)。

  • 不能用于过滤原始行(那是 WHERE 的工作)。

语法:

SELECT 列1, 聚合函数(列2)
FROM 表名
GROUP BY 列1
HAVING 条件;  -- 可以写聚合函数

例子

表 orders 数据:

order_idcustomer_idproductamount
1 101 Laptop 1200
2 102 Mouse 25
3 101 Keyboard 75
4 103 Monitor 300
5 102 Laptop 1100

 

-- 找出销售次数 ≥ 2 的产品
SELECT product, COUNT(*) AS sales_count
FROM orders
GROUP BY product
HAVING COUNT(*) >= 2;

结果:

productsales_count
Laptop 2

 

-- SQL 查询的逻辑执行顺序
FROMWHEREGROUP BY → 聚合计算 → HAVINGSELECTORDER BY → LIMIT
  • WHERE 在分组前运行,只能访问原始列;
  • HAVING 在分组后运行,可以访问分组列 + 聚合结果。

where 和 having 的区别:

  • 执行时机不同:
    • where是分组之前进行过滤,不满足where条件不参与分组;
    • having是分组后对结果进行过滤。
  • 判断条件不同:
    • where不能对聚合函数进行判断,而having可以。
 
posted @ 2025-11-13 14:36  chao_xiong  阅读(11)  评论(0)    收藏  举报