SQL多表百分比计算求助:事件与测试组合的基数占比计算
解决你的SQL测试-事件基数占比计算问题
首先,我明白你需要统计每个测试组合(test_name + version)下,不同交互事件(loaded/clicked)的用户基数,以及该基数占对应测试总用户数的比例。你的思路方向是对的——关联子查询+左连接确实可行,不过我们可以用CTE(公共表表达式)来拆分逻辑,让代码更清晰易读。
最终SQL代码
WITH test_total_users AS ( -- 第一步:计算每个测试组合的总用户数 SELECT test_name, version, COUNT(DISTINCT [user]) AS total_users FROM dbo.tests GROUP BY test_name, version ), test_event_user_counts AS ( -- 第二步:统计每个测试组合下,各事件的用户基数(去重,避免同一用户多次事件重复计数) SELECT t.test_name, t.version, e.event, COUNT(DISTINCT t.[user]) AS event_user_count FROM dbo.tests t LEFT JOIN dbo.events e ON t.[user] = e.[user] GROUP BY t.test_name, t.version, e.event ) -- 第三步:关联两张临时表,计算占比 SELECT te.test_name, te.version, te.event, te.event_user_count AS user_base, -- 转成浮点型避免整数除法,保留4位小数 ROUND(CAST(te.event_user_count AS FLOAT) / tu.total_users, 4) AS base_percentage FROM test_event_user_counts te INNER JOIN test_total_users tu ON te.test_name = tu.test_name AND te.version = tu.version -- 可选:过滤掉无事件的记录 WHERE te.event IS NOT NULL ORDER BY te.test_name, te.version, te.event;
代码逻辑解释
test_total_usersCTE:先按测试组合分组,统计每个测试的总参与用户数(用DISTINCT确保同一用户在同一测试中只算一次)。test_event_user_countsCTE:将测试表和事件表通过user字段左关联,然后按测试组合+事件类型分组,统计每个组的用户数——这里同样用DISTINCT,避免同一用户的多次同类型事件(比如多次loaded)重复计数。- 最终查询:把两个CTE关联,用事件用户数除以测试总用户数得到占比,通过
CAST转浮点型解决SQL整数除法的问题,并用ROUND控制小数位数。
针对你的测试数据的运行结果
| test_name | version | event | user_base | base_percentage |
|---|---|---|---|---|
| bar | B | clicked | 1 | 0.5000 |
| bar | B | loaded | 2 | 1.0000 |
| foo | A | clicked | 1 | 0.5000 |
| foo | A | loaded | 2 | 1.0000 |
这个结果完全符合你的数据情况:比如bar B测试总共有2个用户,其中1个产生了clicked事件(占50%),2个都产生了loaded事件(占100%)。
补充注意事项
- 如果不需要展示无事件的测试-事件组合,可以保留
WHERE te.event IS NOT NULL过滤条件;如果需要查看哪些测试没有用户产生事件,可以去掉这个条件。 - 如果你的数据库支持
DECIMAL类型,也可以用CAST(te.event_user_count AS DECIMAL(10,4))来替代FLOAT,精度会更稳定。
内容的提问来源于stack exchange,提问作者keyrocklawyer
相关产品推荐
相关产品推荐

