MySQL跨Games、Transaction两表如何实现两个聚合值的除法计算
MySQL跨表聚合值除法实现方案
两个需要计算的指标分别来自两张独立的表,直接把两个聚合逻辑写成标量子查询做交叉关联后运算即可,不需要额外的关联条件。
基础全表统计写法
对应全表维度计算需求(即全表Games聚合值/全表Transaction去重用户数),代码如下:
SELECT g.total_rake_calc / NULLIF(t.distinct_user_count, 0) AS final_result FROM (SELECT SUM(EntryFee * Rake/(100 + Rake)*TotalEntry) AS total_rake_calc FROM Games) AS g CROSS JOIN (SELECT COUNT(DISTINCT UserID) AS distinct_user_count FROM `Transaction`) AS t;
代码说明
- 两个子查询分别独立完成单表的聚合计算:
- 子查询
g计算Games表中你需要的抽成总和值 - 子查询
t计算Transaction表的去重用户数,注意Transaction是MySQL保留字,表名必须用反引号包裹避免语法报错
- 子查询
CROSS JOIN用于关联两个仅返回单行结果的聚合集,不会产生笛卡尔积冗余问题NULLIF(t.distinct_user_count, 0)用于做除零保护:当去重用户数为0时,运算结果返回NULL,避免触发分母为0的SQL报错;如果你需要分母为0时返回0,可以在外层套一层IFNULL,写法改成IFNULL(g.total_rake_calc / NULLIF(t.distinct_user_count, 0), 0) AS final_result即可。
按照你举的示例,当total_rake_calc为90、distinct_user_count为3时,语句返回结果为30,符合预期。
分组统计扩展写法
如果你需要按特定维度(比如日期、游戏场次)分组后,计算每组对应的两个指标的除法结果,只需要在两个子查询中增加相同的分组字段,再通过分组字段关联即可,以按天统计为例:
SELECT g.stat_date, g.total_rake_calc / NULLIF(t.distinct_user_count, 0) AS daily_avg_result FROM ( SELECT DATE(GameStartTime) AS stat_date, SUM(EntryFee * Rake/(100 + Rake)*TotalEntry) AS total_rake_calc FROM Games GROUP BY DATE(GameStartTime) ) AS g INNER JOIN ( SELECT DATE(TransTime) AS stat_date, COUNT(DISTINCT UserID) AS distinct_user_count FROM `Transaction` GROUP BY DATE(TransTime) ) AS t ON g.stat_date = t.stat_date;
内容的提问来源于stack exchange,提问作者Yogesh
相关产品推荐
相关产品推荐

