如何使用单条MySQL查询获取列值的相对计数/频率
单条SQL查询计算列值的相对频率(无需提前统计总行数)
完全理解你的需求!用窗口函数就能轻松实现单条查询算出每个值的相对计数/频率,不管是单表还是多表连接场景,都不用单独去统计总行数,比用变量的方式简洁太多了。
解决方案代码
直接用COUNT(*) OVER()来获取全局的总行数,然后用每个分组的计数除以这个全局总数即可:
SELECT num, ROUND(COUNT(*) / COUNT(*) OVER(), 3) AS count FROM numbers GROUP BY num ORDER BY num ASC;
为什么这个方法好用?
COUNT(*) OVER()是窗口函数,它会计算整个结果集的总行数(也就是原表的总记录数),不需要单独写子查询或者设置变量。- 当你需要做多表连接查询时,这个方法依然适用——只要把
FROM numbers换成你的连接语句就行,全局总数会自动计算连接后的总记录数,不用额外写冗长的子查询去统计。
示例验证
用你给出的numbers表测试:
原表数据:
num
1
2
3
1
1
2
1
0
执行上面的SQL后,会得到和你期望完全一致的结果:
| num | count |
|---|---|
| 0 | 0.125 |
| 1 | 0.5 |
| 2 | 0.25 |
| 3 | 0.125 |
扩展说明
如果你的场景里需要排除某些值(比如NULL),可以在窗口函数里加条件,比如:
COUNT(*) OVER(WHERE num IS NOT NULL)
这样全局总数就会只统计非NULL的记录数,按需调整即可。
内容的提问来源于stack exchange,提问作者Fibo Kowalsky
相关产品推荐
相关产品推荐

