如何修复SQL查询中WHERE子句使用count聚合函数的报错问题
你遇到的报错是SQL语法的通用规则限制:
An aggregate may not appear in the
WHEREclause unless it is in a subquery contained in aHAVINGclause or a select list, and the column being aggregated is an outer reference.
报错根因
SQL的执行顺序里,WHERE子句的优先级高于聚合计算,它负责在分组前逐行过滤原始数据,这时候count()、sum()这类聚合函数还没有执行,拿不到计算结果,所以不能直接把count(A.Att_check)写在WHERE的判断条件里。
除此之外你的原SQL还有两个会导致结果错误的问题:
- 使用旧式逗号隐式连表,没有提前聚合考勤数据,两表直接关联会产生笛卡尔积,最终统计的出勤天数完全失真
- SELECT列表中直接使用
count()聚合函数,但没有配套写GROUP BY分组规则,本身也不符合SQL语法要求
修正方案
不要在WHERE中直接判断聚合结果,先通过子查询提前按员工分组统计好实际出勤天数,再和薪资表关联计算总薪资即可,修正后的可运行代码如下:
SELECT S.Employee_ID, ((S.Salary / 30) * A.attend_days + S.Bonus - S.Loan) AS TotalSalary FROM Salary AS S INNER JOIN ( -- 子查询内提前完成每个员工的出勤天数统计,聚合逻辑合法 SELECT Employee_ID, COUNT(Att_check) AS attend_days FROM Attendance WHERE Att_check = 'attend' GROUP BY Employee_ID ) AS A ON S.Employee_ID = A.Employee_ID
如果硬要在原有写法结构上调整(不推荐,极易出现统计错误),需要把聚合过滤条件移到HAVING子句中,同时补全GROUP BY字段,但这种写法因为连表逻辑的天然缺陷,统计出的总薪资大概率是错误的,禁止在生产环境使用。
内容的提问来源于stack exchange,提问作者Nguyen Minh Duc FGW HN
相关产品推荐
相关产品推荐

