使用CASE表达式分类房价时计算占比报错的解决方法
解决SQL聚合嵌套错误并计算类别占比
错误原因
你遇到的错误Cannot perform an aggregate function on an expression containing an aggregate or a subquery,是因为在聚合函数sum()里直接嵌套了另一个聚合函数count(*)。SQL不允许这种嵌套操作——count(*)是分组后每个类别的统计数,而sum(count(*))试图在分组层面再次聚合,引擎无法直接解析这种逻辑。
解决方案一:使用窗口函数(推荐)
窗口函数SUM(COUNT(*)) OVER ()可以在分组的同时,计算出全局的总记录数,这样就能直接用每个组的数量除以总数得到占比。修改后的代码如下:
SELECT Price_Range, COUNT(*) AS Property_Number, CONCAT(ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2), '%') AS Percentage FROM ( SELECT (CASE WHEN PMP.Median_Price > 2500000 THEN '$2.5M+' WHEN PMP.Median_Price > 1500000 THEN '$1.5M-$2.5M' WHEN PMP.Median_Price > 750000 THEN '$750K-$1.5M' WHEN PMP.Median_Price <= 750000 THEN '0-$750K' END) AS Price_Range FROM Property_Median_Price AS PMP ) PMP GROUP BY Price_Range ORDER BY Property_Number DESC;
关键说明
SUM(COUNT(*)) OVER ():OVER ()表示在整个结果集上计算总和,也就是所有分组的count(*)相加,得到表的总记录数。- 乘以
100.0是为了避免整数除法(如果直接用count(*)/sum(...),整数相除会得到0或1,无法得到小数占比)。 ROUND(..., 2)用于保留2位小数,你可以根据需求调整位数。
解决方案二:先计算总记录数再关联
如果你的SQL版本不支持窗口函数(比如旧版MySQL),可以先单独算出总记录数,再和分组统计结果关联:
WITH Total_Count AS ( SELECT COUNT(*) AS Total FROM Property_Median_Price ) SELECT PMP.Price_Range, COUNT(*) AS Property_Number, CONCAT(ROUND(COUNT(*) * 100.0 / TC.Total, 2), '%') AS Percentage FROM ( SELECT (CASE WHEN Median_Price > 2500000 THEN '$2.5M+' WHEN Median_Price > 1500000 THEN '$1.5M-$2.5M' WHEN Median_Price > 750000 THEN '$750K-$1.5M' WHEN Median_Price <= 750000 THEN '0-$750K' END) AS Price_Range FROM Property_Median_Price ) PMP CROSS JOIN Total_Count TC GROUP BY PMP.Price_Range, TC.Total ORDER BY Property_Number DESC;
关键说明
- 用CTE(
WITH子句)先算出总记录数,也可以用子查询代替CTE。 CROSS JOIN将分组结果和总记录数表关联,这样每个组都能拿到总数量用于计算占比。
内容的提问来源于stack exchange,提问作者TomFZ
相关产品推荐
相关产品推荐

