SQL中如何统计全年数据总和?关于John 2013年消费总额查询的正确性疑问
关于SQL统计全年消费总额的问题
你的这段代码大概率无法得到正确的结果,我来帮你拆解问题并给出修正方案:
核心问题分析
不必要的表关联导致重复计算
你关联了Order_表,但查询中完全没用到这个表的字段。如果一个OrderHead(订单头)对应多条Order_记录(比如一个订单包含多个商品明细),那么关联后同一个b.Amount_Total会被重复输出多次。SUM(DISTINCT)的风险
你用SUM(DISTINCT b.Amount_Total)试图解决重复计算,但如果用户有两个不同的订单恰好金额完全相同,DISTINCT会把这两个金额合并成一个值,直接导致总额少算。
修正后的方案
方案1:去掉不必要的表关联(推荐)
既然你不需要Order_表的任何数据,直接删掉这个关联,就能避免重复计算问题:
SELECT FORMAT(SUM(b.Amount_Total), 'c') FROM Customer a INNER JOIN OrderHead b ON a.Customer_Id = b.Customer_Id WHERE a.Name = 'John Smith' AND b.Order_date >= '2013/01/01' AND b.Order_date < '2014/01/01'
这里把日期条件改成>= '2013/01/01' AND < '2014/01/01',是为了避免漏掉2013年12月31日当天晚些时候的订单(如果Order_date是带时间的datetime类型,BETWEEN会只包含到2013-12-31 00:00:00)。
方案2:必须关联Order_表时的写法
如果你后续需要基于Order_表加筛选条件,那可以先通过子查询去重订单,再求和:
SELECT FORMAT(SUM(order_total), 'c') FROM ( -- 先获取用户2013年的所有唯一订单及对应总额 SELECT DISTINCT b.Order_Id, b.Amount_Total AS order_total FROM Customer a INNER JOIN OrderHead b ON a.Customer_Id = b.Customer_Id INNER JOIN Order_ c ON b.Order_Id = c.Order_Id WHERE a.Name = 'John Smith' AND b.Order_date >= '2013/01/01' AND b.Order_date < '2014/01/01' ) AS customer_orders
这种写法既保留了和Order_表的关联,又能确保每个订单的总额只被计算一次,不会因为相同金额的订单出错。
内容的提问来源于stack exchange,提问作者Pacman
相关产品推荐
相关产品推荐

