SQL141 返回顾客名称和相关订单号以及每个订单的总价

描述

Customers 表有字段,顾客名称:cust_name、顾客id:cust_id

cust_idcust_name
cust10andy
cust1ben
cust2tony
cust22tom
cust221an
cust2217hex

Orders订单信息表,含有字段,订单号:order_num、顾客id:cust_id

order_numcust_id
a1cust10
a2cust1
a3cust2
a4cust22
a5cust221
a7cust2217

OrderItems表有字段,商品订单号:order_num、商品数量:quantity、商品价格:item_price

order_numquantityitem_price
a1100010
a220010
a31015
a42550
a51525
a777

【问题】

除了返回顾客名称和订单号,返回 Customers 表中的顾客名称(cust_name)和Orders 表中的相关订单号(order_num),添加第三列 OrderTotal,其中包含每个订单的总价,并按顾客名称再按订单号对结果进行升序排序。

【示例结果】返回顾客名称 cust_name、订单号order_num、订单总额OrderTotal

cust_nameorder_numOrderTotal
ana5375
andya110000
bena22000
hexa749
toma41250
tonya315


【示例解析】

例如顾客名称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;

易错点 :聚合函数使用不当

聚合函数(如 SUMCOUNTAVG 等)是 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

🔁 执行顺序:

  1. FROM → JOIN

  2. WHERE(过滤行,不能用聚合)

  3. GROUP BY

  4. HAVING(过滤组,可以用聚合)

  5. SELECT

  6. ORDER BY


✅ 正确使用聚合函数的 checklist

检查项是否满足
使用了 SUM()COUNT() 等聚合函数?
所有非聚合字段都在 GROUP BY 中?✅ cust_nameorder_num
GROUP BY 字段完整?
聚合条件用 HAVING 而不是 WHERE✅(如果需要)
连接条件正确?✅ ON 匹配主外键

✅ 总结:聚合函数使用原则

原则说明
📌 有聚合,必有 GROUP BY除非你真的要整个表的总和
📌 GROUP BY 要包含所有非聚合字段否则语法错误或逻辑错误
📌 聚合函数不能在 WHERE 中使用用 HAVING 替代
📌 理解 SUM 是“组内求和”不是“每行计算”

💡 口诀记忆

“一用 SUM 就分组,非聚字段都要抱;WHERE 不能用 SUM,HAVING 才是好伙伴。”


你这条 SQL 写得很标准,只要记住这些易错点,就能避免 90% 的聚合函数问题!继续加油!💪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值