SQL中的group by和having区别详解
理解 SQL 中的 GROUP BY
和 HAVING
是掌握数据分析的关键。
🧩 核心概念:分组与过滤
GROUP BY
:将数据分组(类似 Excel 的数据透视表)HAVING
:对分组后的结果进行过滤(类似WHERE
,但作用于分组)
📊 类比现实场景
想象你是一家超市的经理,有一张销售记录表(sales
):
商品类别 | 销售额 | 日期 |
---|---|---|
水果 | 100 | 2023-01-01 |
蔬菜 | 80 | 2023-01-01 |
水果 | 120 | 2023-01-02 |
饮料 | 150 | 2023-01-02 |
蔬菜 | 90 | 2023-01-03 |
1️⃣ 只用 GROUP BY
(分组统计)
SELECT 商品类别, SUM(销售额) AS 总销售额 -- 聚合函数
FROM sales
GROUP BY 商品类别; -- 按类别分组
结果:
商品类别 | 总销售额 |
---|---|
水果 | 220 |
蔬菜 | 170 |
饮料 | 150 |
💡 关键点:
GROUP BY
把相同类别的行"折叠"成一行,配合聚合函数(SUM/AVG/COUNT
等)计算
2️⃣ GROUP BY
+ HAVING
(分组后过滤)
SELECT 商品类别,SUM(销售额) AS 总销售额
FROM sales
GROUP BY 商品类别
HAVING SUM(销售额) > 200; -- 只保留总销售额>200的分组
结果:
商品类别 | 总销售额 |
---|---|
水果 | 220 |
🚨 注意:
HAVING
在分组后执行,用于过滤分组结果
🔍 WHERE
vs HAVING
关键区别
-- WHERE: 分组前过滤原始数据(单行级别)
SELECT 类别, SUM(销售额)
FROM sales
WHERE 日期 = '2023-01-02' -- 先过滤日期
GROUP BY 类别-- HAVING: 分组后过滤聚合结果(分组级别)
SELECT 类别, SUM(销售额)
FROM sales
GROUP BY 类别
HAVING SUM(销售额) > 200 -- 后过滤聚合值
🌰 实际应用场景
需求: 找出平均订单额超过 $50 的客户
SELECT customer_id,AVG(order_amount) AS avg_order
FROM orders
GROUP BY customer_id
HAVING AVG(order_amount) > 50; -- 对分组结果过滤
⚠️ 常见错误与避坑指南
-
SELECT
非聚合字段-- 错误!product_name未在GROUP BY中声明 SELECT category, product_name, COUNT(*) FROM products GROUP BY category;
-
混淆
WHERE
和HAVING
-- 错误!WHERE不能使用聚合函数 SELECT category, AVG(price) FROM products WHERE AVG(price) > 100 -- 应改用HAVING GROUP BY category;
-
分组后排序
SELECT category, COUNT(*) AS product_count FROM products GROUP BY category HAVING COUNT(*) > 5 ORDER BY product_count DESC; -- 正确用法
💡 记忆口诀
“GROUP BY 先分组,HAVING 后过滤”
“WHERE 管单行,HAVING 管分组”