SQL统计占比的核心是分子除以分母乘100,需确保分母准确(全局/分组/固定值),处理NULL、整数除法和小数精度;常用COUNT(CASE WHEN...)、窗口函数、NULLIF及浮点强制转换。
SQL中统计占比(即百分比)的核心思路是:用某部分的数值除以总体数值,再乘以100,并注意处理小数精度和NULL值。关键不在函数多复杂,而在分母是否准确、是否需要全局总计或分组内总计。
适用于计算满足某条件的记录占全表比例,例如“订单中已支付订单占比”:
SELECT
ROUND(
COUNT(CASE WHEN status = 'paid' THEN 1 END) * 100.0 / COUNT(*),
2
) AS paid_ratio
FROM orders;
COUNT(CASE WHEN ...)统计分子,避免COUNT(*)忽略NULL导致偏差COUNT(*)确保包含所有行(包括status为NULL的记录)* 100.0强制转为浮点数,防止整数除法截断(尤其在MySQL/PostgreSQL中)ROUND(..., 2)保留两位小数,更符合业务展示习惯例如“各城市中,不同订单状态的占比”——需用窗口函数实现组内归一化:
SELECT
city,
status,
COUNT(*) AS cnt,
ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (PARTITION BY city), 2) AS ratio_in_city
FROM orders
GROUP BY city, status;
SUM(COUNT(*)) OVER (PARTITION BY city)先按city分组聚合,再对每组求和,得到每个城市的总订单数
不能直接在SELECT中嵌套普通聚合PARTITION BY status)当分母是外部给定值(如销售目标1000万元),可用子查询或WITH定义:
WITH target AS (SELECT 1000.0 AS amount)
SELECT
ROUND(SUM(amount) * 100.0 / (SELECT amount FROM target), 2) AS completion_rate
FROM sales;
1000.0避免整除问题以下写法容易出错,需特别注意:
NULLIF(denominator, 0)防止报错,如num * 100.0 / NULLIF(total, 0)
5 / 8结果是0,必须写成5.0 / 8或CAST(5 AS FLOAT) / 8
ORDER BY子句