SQL查询报错:筛选总消费高于平均消费的客户名称失败
解决SQL查询错误并实现需求
错误原因分析
你遇到的Error Code: 1054错误,是因为HAVING子句里直接引用了未聚合的列O.TotalPaid。在GROUP BY分组后,HAVING只能使用分组键(这里是O.CustomerID)或者聚合函数的结果,不能直接引用单条记录的列值。另外你的逻辑也有问题:原代码用<是找低于分组内平均的客户,和你要的“总购买金额高于全局平均”需求相反,而且Avg(O.TotalPaid)是每个客户自己订单的平均,不是所有订单的全局平均。
正确实现方案
根据你的需求“展示总购买金额高于所有订单平均购买金额的客户姓名”,分两种常见场景给出实现:
场景1:客户总消费 > 所有单笔订单的平均金额
如果你的“所有订单平均购买金额”指的是每一笔订单的平均金额,用下面的查询:
SELECT C.FirstName FROM CUSTOMERS AS C JOIN ( -- 先统计每个客户的总消费,筛选出总消费大于全局订单平均的客户 SELECT CustomerID, SUM(TotalPaid) AS TotalSpent FROM ORDERS GROUP BY CustomerID HAVING SUM(TotalPaid) > (SELECT AVG(TotalPaid) FROM ORDERS) ) AS CustomerTotals ON C.CustomerID = CustomerTotals.CustomerID;
场景2:客户总消费 > 所有客户的平均总消费金额
如果你的需求是客户总消费高于所有客户总消费的平均值(比如A客户总花1000,B花2000,C花3000,平均总消费是2000,筛选出B和C),用这个查询:
SELECT C.FirstName FROM CUSTOMERS AS C JOIN ( SELECT CustomerID, SUM(TotalPaid) AS TotalSpent FROM ORDERS GROUP BY CustomerID ) AS CustomerTotals ON C.CustomerID = CustomerTotals.CustomerID -- 子查询先算出所有客户总消费的平均值,再筛选符合条件的客户 WHERE CustomerTotals.TotalSpent > ( SELECT AVG(TotalSpent) FROM ( SELECT SUM(TotalPaid) AS TotalSpent FROM ORDERS GROUP BY CustomerID ) AS AllCustomerTotals );
补充说明
原代码中SELECT C.FirstName搭配GROUP BY O.CustomerID,在开启ONLY_FULL_GROUP_BY的SQL模式下会报错,因为FirstName不在分组键中也不是聚合结果。上面的方案通过子查询先处理订单聚合,再关联客户表,避免了这个问题。
内容的提问来源于stack exchange,提问作者Sebastian Llaurador
相关产品推荐
相关产品推荐

