如何编写SQL计算多行重复名称对应布尔转化列的转化率
转化率计算SQL实现
默认业务表名为user_conversion,核心计算逻辑为:单名称下转化成功记录数 / 单名称下总记录数,布尔类型字段Converted取值为TRUE时计为1次转化,FALSE计为0次。
需求1:按名称聚合输出,每个名称仅返回1行转化率结果
使用GROUP BY按名称分组聚合即可,标准SQL写法兼容绝大多数数据库:
SELECT Name, SUM(CASE WHEN Converted = TRUE THEN 1 ELSE 0 END) / COUNT(*) AS `Conversion Rate` FROM user_conversion GROUP BY Name;
- 若需要返回百分比格式结果,可将计算逻辑修改为
CONCAT(ROUND(SUM(CASE WHEN Converted = TRUE THEN 1 ELSE 0 END) / COUNT(*) * 100, 2), '%'),可直接得到50%/75%这类可读性更高的结果 - 对于支持布尔值隐式转数值的数据库(如PostgreSQL、MySQL 8.0+),可简化
SUM逻辑为SUM(Converted),布尔值TRUE会自动识别为1、FALSE识别为0
需求2:保留全量原始明细行,新增同组转化率列
支持窗口函数的数据库(MySQL 8.0+、PostgreSQL、Hive、Spark SQL等)
使用窗口函数按Name分区计算,不需要聚合缩行,同名称下所有行的转化率数值完全一致:
SELECT *, SUM(CASE WHEN Converted = TRUE THEN 1 ELSE 0 END) OVER (PARTITION BY Name) / COUNT(*) OVER (PARTITION BY Name) AS `Conversion Rate` FROM user_conversion;
不支持窗口函数的旧版数据库(如MySQL 5.x)
通过子查询先聚合得到每个名称的转化率,再左关联回原表明细即可:
SELECT t1.*, t2.conv_rate AS `Conversion Rate` FROM user_conversion t1 LEFT JOIN ( SELECT Name, SUM(CASE WHEN Converted = TRUE THEN 1 ELSE 0 END)/COUNT(*) AS conv_rate FROM user_conversion GROUP BY Name ) t2 ON t1.Name = t2.Name;
上述写法已匹配示例数据计算规则:名称abc返回0.5、dhk返回0.75、xyz返回0,和预期结果完全一致。
内容的提问来源于stack exchange,提问作者Avrahad
相关产品推荐
相关产品推荐

