先问一行代表什么
数据库课程辅导中,语法正确不等于结果正确。为每张表写出行粒度,例如 customers 一行一个客户,orders 一行一张订单,order_items 一行一个订单商品。连接键应该反映这些关系。
SQL连接查询辅导可以先不用电脑:把连接前后会出现的行画在纸上。PostgreSQL 官方教程分别讲解表连接和聚合,这两个步骤解决的问题不同。
原创订单练习:150 为什么变成 250
假设订单 O1 的金额是 100,有两条商品记录;O2 的金额是 50,有一条商品记录。按 order_id 将订单连接到商品后,会出现 O1、O1、O2 三行。此时 SUM(order_total) 得到 250,而订单总金额应为 150。
错误不是 SUM 不会加数,而是订单金额被复制到商品粒度。按订单先取得所需商品汇总,再与每订单一行的表连接,或在只需订单总额时直接从订单表计算。
GROUP BY 不能自动修复重复
SQL聚合函数辅导要检查每组的来源行。GROUP BY customer_id 只是把已连接的行分组,不能让重复的订单金额自动只算一次。SUM(DISTINCT order_total) 也不是通用修复:两个不同订单金额相同,就会被错误合并。
只有需要商品层面的总价时,才应根据商品数量与单价的定义计算明细值。先写出业务含义,再选聚合表达式。
自查:没有订单的客户算几次
大学数据库模块辅导可再加入客户 C3,其没有订单。customers LEFT JOIN orders 会保留 C3 并产生订单列为 NULL 的一行。按客户分组时 COUNT(*) 是 1;若 order_id 为非空订单标识,COUNT(order_id) 才是 0。
把有两张订单、一张订单和零订单的三个客户都列入手算答案。先核对行数,再核对总额,最后解释为什么 WHERE 与 HAVING 的筛选时机不同。练习使用虚构数据,提交作业由学生自行完成。
参考资料
下一步
如需讨论相关大学专业课程辅导,请说明模块名称、学习目标和自己已经尝试的步骤。能否安排合适的教学须经确认,所有课程作业由学生独立完成。
