如何在PostgreSQL中计算满足条件的行占比?
计算满足条件行的占比的正确SQL写法
你的原语句报错,是因为多数数据库不允许直接将两个子查询的除法结果作为裸返回值,必须包裹在SELECT语句中。以下几种写法都可以实现需求:
方法1:修正你的原始写法
给整个除法表达式套一层SELECT,指定别名方便查看结果:
SELECT (SELECT COUNT(*) FROM table WHERE col_name > crit) / (SELECT COUNT(*) FROM table) AS condition_ratio;
注意:如果数据库默认整数除法会截断小数(比如MySQL、SQL Server),可以把其中一个子查询的结果转成浮点型,避免得到整数结果:
SELECT (SELECT COUNT(*) FROM table WHERE col_name > crit) / (SELECT CAST(COUNT(*) AS FLOAT) FROM table) AS condition_ratio;
方法2:更高效的单表扫描写法
上面的方法会扫描两次表,下面的写法只扫描一次,性能更好:
SELECT SUM(CASE WHEN col_name > crit THEN 1 ELSE 0 END)::FLOAT / COUNT(*) AS condition_ratio FROM table;
SUM(CASE...)统计符合条件的行数::FLOAT是PostgreSQL的类型转换方式,其他数据库可以用CAST(COUNT(*) AS FLOAT)或者COUNT(*)*1.0来强制浮点运算
方法3:用AVG简化写法
利用AVG函数计算0/1值的平均值,直接得到占比:
SELECT AVG(CASE WHEN col_name > crit THEN 1.0 ELSE 0 END) AS condition_ratio FROM table;
这里返回1.0而不是1,是为了让数据库按浮点型计算,避免整数除法问题。
针对MySQL的简化写法
MySQL支持IF函数,可以替换CASE:
SELECT AVG(IF(col_name > crit, 1.0, 0)) AS condition_ratio FROM table;
内容的提问来源于stack exchange,提问作者WolfiG
相关产品推荐
相关产品推荐

