如何在PostgreSQL查询结果中添加占比列(Azure Data Studio)
问题:为PostgreSQL查询添加分组占总数量的百分比列
问题背景
现有查询代码用于统计不同客户状态的数量:
SELECT customer_status.status AS "Status of Customer", COUNT (customer_bio) AS "Number" FROM customer_status JOIN customer_bio ON customer_status.status_id=customer_bio.status_id GROUP BY status
当前输出:
| Status of Customer | Number |
|---|---|
| Switched Off | 352 |
| Out of Town | 743 |
| Not reachable | 564 |
| Active | 13738 |
| Relocated | 78 |
需要新增一列,计算每组数量占总数的百分比(例如Switched Off为352/总数*100),尝试的代码如下:
SELECT customer_status.status AS "Status of Customer", count(customer_bio) AS "Number", count(customer_bio)/count(*) * 100 AS "Percentage" FROM customer_status JOIN customer_bio ON customer_status.status_id=customer_bio.status_id GROUP BY status
但得到的百分比全为100%:
| Status of Customer | Number | Percentage |
|---|---|---|
| Switched Off | 352 | 100 |
| Out of Town | 743 | 100 |
| Not reachable | 564 | 100 |
| Active | 13738 | 100 |
| Relocated | 78 | 100 |
使用环境:通过Azure Data Studio连接的PostgreSQL。
问题原因
在GROUP BY status之后,count(*)统计的是当前分组内的行数,和count(customer_bio)结果一致,所以两者相除等于1,乘以100后得到100%,这不是你需要的全局总数占比。
解决方案
在PostgreSQL中,可以使用窗口函数COUNT(*) OVER()来获取全局的总记录数,同时需要注意处理整数除法(避免结果被截断为整数),将其中一个数值转换为浮点类型:
SELECT customer_status.status AS "Status of Customer", COUNT(customer_bio) AS "Number", -- 转换为numeric避免整数截断,计算占比后保留两位小数 ROUND(COUNT(customer_bio)::NUMERIC / COUNT(*) OVER() * 100, 2) AS "Percentage" FROM customer_status JOIN customer_bio ON customer_status.status_id = customer_bio.status_id GROUP BY status
说明:
COUNT(*) OVER():窗口函数,不指定分区时会计算整个结果集的总记录数,也就是所有客户的总数。::NUMERIC:将分组计数转换为数值类型,确保除法运算得到浮点结果,避免整数除法导致的精度丢失。ROUND(..., 2):将百分比结果保留两位小数,让输出更整洁。
执行后会得到正确的百分比列,例如Switched Off的百分比会是352/(352+743+564+13738+78)*100的计算结果。
内容的提问来源于stack exchange,提问作者Jaymes
相关产品推荐
相关产品推荐

