描述
Customers 表有字段,顾客名称:cust_name、顾客id:cust_id
| cust_id | cust_name |
| cust10 | andy |
| cust1 | ben |
| cust2 | tony |
| cust22 | tom |
| cust221 | an |
| cust2217 | hex |
Orders订单信息表,含有字段,订单号:order_num、顾客id:cust_id
| order_num | cust_id |
| a1 | cust10 |
| a2 | cust1 |
| a3 | cust2 |
| a4 | cust22 |
| a5 | cust221 |
| a7 | cust2217 |
OrderItems表有字段,商品订单号:order_num、商品数量:quantity、商品价格:item_price
| order_num | quantity | item_price |
| a1 | 1000 | 10 |
| a2 | 200 | 10 |
| a3 | 10 | 15 |
| a4 | 25 | 50 |
| a5 | 15 | 25 |
| a7 | 7 | 7 |
【问题】
除了返回顾客名称和订单号,返回 Customers 表中的顾客名称(cust_name)和Orders 表中的相关订单号(order_num),添加第三列 OrderTotal,其中包含每个订单的总价,并按顾客名称再按订单号对结果进行升序排序。
【示例结果】返回顾客名称 cust_name、订单号order_num、订单总额OrderTotal
| cust_name | order_num | OrderTotal |
| an | a5 | 375 |
| andy | a1 | 10000 |
| ben | a2 | 2000 |
| hex | a7 | 49 |
| tom | a4 | 1250 |
| tony | a3 | 15 |
【示例解析】
例如顾客名称cust_name为an的顾客的订单a5的订单总额为quantity*item_price = 15 * 25 = 375,最后以cust_name和order_num来进行升序排序。
SELECT
c.cust_name,
o.order_num,
SUM(oi.quantity * oi.item_price) AS OrderTotal
FROM Customers c
JOIN Orders o ON c.cust_id = o.cust_id
JOIN OrderItems oi ON oi.order_num = o.order_num
GROUP BY c.cust_name, o.order_num
ORDER BY c.cust_name, o.order_num;
易错点 :聚合函数使用不当
聚合函数(如 SUM、COUNT、AVG 等)是 SQL 中强大但极易出错的功能。以下是常见错误和正确理解。
❌ 易错点 1:忘记写 GROUP BY
错误示例:
SELECT c.cust_name, o.order_num, SUM(oi.quantity * oi.item_price)
FROM Customers c JOIN Orders o ON ...
JOIN OrderItems oi ON ...
-- 缺少 GROUP BY
❌ 报错或结果错误:
-
在大多数数据库(如 MySQL 严格模式、PostgreSQL、SQL Server)中会直接报错:
ERROR: column "c.cust_name" must appear in GROUP BY clause -
在宽松的 MySQL 中可能“侥幸运行”,但结果不可靠、无意义。
✅ 正确做法:
只要使用了聚合函数,且查询中包含非聚合字段,就必须使用
GROUP BY!
GROUP BY c.cust_name, o.order_num
❌ 易错点 2:GROUP BY 字段不完整
错误示例:
GROUP BY o.order_num -- 只按订单号分组
❌ 问题:
-
c.cust_name没有出现在GROUP BY中 -
虽然
order_num唯一,但 SQL 要求:所有非聚合字段都必须出现在GROUP BY中 -
否则会报错(标准 SQL 要求)
✅ 正确做法:
GROUP BY c.cust_name, o.order_num
保证
SELECT中的每个非聚合字段都在GROUP BY中
❌ 易错点 3:误以为 SUM() 自动按行计算
常见误解:
“
SUM(quantity * item_price)是每行的乘积,所以不需要GROUP BY。”
❌ 错误理解:
-
SUM()是聚合函数,它会对一组行求和,返回一个值 -
如果不
GROUP BY,它会把整个结果集的所有quantity * item_price加起来,返回一个总数,而不是每个订单的金额
✅ 正确认识:
-
SUM()本身不“按行”计算 -
必须通过
GROUP BY定义“组”,SUM才能对每组分别求和
❌ 易错点 4:混淆 WHERE 和 HAVING
错误示例(想筛选订单总金额 > 1000 的):
WHERE SUM(oi.quantity * oi.item_price) > 1000 -- ❌ 错误!
❌ 报错:
WHERE不能用聚合函数
✅ 正确做法:
HAVING SUM(oi.quantity * oi.item_price) > 1000
🔁 执行顺序:
-
FROM→JOIN -
WHERE(过滤行,不能用聚合) -
GROUP BY -
HAVING(过滤组,可以用聚合) -
SELECT -
ORDER BY
✅ 正确使用聚合函数的 checklist
| 检查项 | 是否满足 |
|---|---|
使用了 SUM()、COUNT() 等聚合函数? | ✅ |
所有非聚合字段都在 GROUP BY 中? | ✅ cust_name, order_num |
GROUP BY 字段完整? | ✅ |
聚合条件用 HAVING 而不是 WHERE? | ✅(如果需要) |
| 连接条件正确? | ✅ ON 匹配主外键 |
✅ 总结:聚合函数使用原则
| 原则 | 说明 |
|---|---|
📌 有聚合,必有 GROUP BY | 除非你真的要整个表的总和 |
📌 GROUP BY 要包含所有非聚合字段 | 否则语法错误或逻辑错误 |
📌 聚合函数不能在 WHERE 中使用 | 用 HAVING 替代 |
📌 理解 SUM 是“组内求和” | 不是“每行计算” |
💡 口诀记忆
“一用 SUM 就分组,非聚字段都要抱;WHERE 不能用 SUM,HAVING 才是好伙伴。”
你这条 SQL 写得很标准,只要记住这些易错点,就能避免 90% 的聚合函数问题!继续加油!💪
953

被折叠的 条评论
为什么被折叠?



