SQL中如何合并两个COUNT查询结果相除计算每位组织者的活动接受率
SQL活动接受率计算解决方案
你之前出现「子查询返回超过1行」的报错,是因为做除法时没有将两个统计结果按friend_ID逐行匹配,子查询直接返回了所有用户的统计值,数据库无法判断具体取哪一行做计算。
以下是两种可行的实现方案:
方案一:CTE关联统计(可读性高,易维护)
先将两个统计逻辑封装为公用表表达式,再按friend_ID关联后计算比例:
WITH total_events AS ( -- 统计每位好友举办的总活动数 SELECT friend_ID, COUNT(*) as TotalNumberOfEventHosted FROM EVENT_ GROUP BY friend_ID ), confirmed_events AS ( -- 统计每位好友的已确认活动数 SELECT friend_ID, COUNT(*) as NbrOfConfirmedEvent FROM EVENT_ NATURAL JOIN PROPOSED_DATE WHERE IS_CONFIRMED = TRUE GROUP BY friend_ID ) SELECT t.friend_ID, -- 计算接受率,默认保留两位小数的百分比格式 ROUND( IFNULL(c.NbrOfConfirmedEvent, 0) / t.TotalNumberOfEventHosted * 100, 2 ) AS event_accept_rate_percent FROM total_events t LEFT JOIN confirmed_events c ON t.friend_ID = c.friend_ID;
方案二:单轮分组统计(性能更优)
不需要拆分多个子查询,直接在一次分组中完成两个指标的统计,适合数据量较大的场景:
SELECT friend_ID, COUNT(*) AS TotalNumberOfEventHosted, SUM(IF(p.IS_CONFIRMED = TRUE, 1, 0)) AS NbrOfConfirmedEvent, ROUND( SUM(IF(p.IS_CONFIRMED = TRUE, 1, 0)) / COUNT(*) * 100, 2 ) AS event_accept_rate_percent FROM EVENT_ e NATURAL JOIN PROPOSED_DATE p GROUP BY friend_ID;
注意事项
- 两种方案都默认保留了没有已确认活动的组织者记录,对应接受率为0,不需要的话可以把LEFT JOIN改为INNER JOIN
- 如果不需要百分比格式,去掉代码里的
*100即可 - NATURAL JOIN会自动匹配两个表的同名字段做关联,若后续表结构可能变动,推荐手动写明关联字段更稳妥
内容的提问来源于stack exchange,提问作者Vico Lays
相关产品推荐
相关产品推荐

