SQL逐行计算列值占该列总值的方法(分组计数场景)
SQL逐行计算列值占比实现方案
问题背景
现有包含Name、Salary两个字段的表,原始数据如下:
| Name | Salary |
|---|---|
| Amit | 1000 |
| Harsh | 2000 |
| Priya | 5000 |
| Priya | 4000 |
需要生成两个计算字段:
count:统计每个Name在全表中的出现次数rate:当前行count值除以全表总记录数,即对应姓名出现次数占总记录数的比例
预期输出结果:
| Name | Count | Rate |
|---|---|---|
| Amit | 1 | 0.25 |
| Harsh | 1 | 0.25 |
| Priya | 2 | 0.5 |
原SQL报错原因
你之前写的语句无法正常运行,核心问题有3个:
table是SQL标准保留关键字,不能直接作为表名使用,实际运行请替换为真实表名- 同一层
SELECT查询中,不支持直接引用同级别定义的字段别名count参与计算 - 搭配
GROUP BY name使用普通SUM()聚合时,计算范围是单个姓名对应的分组,无法拿到全表总记录数作为比例计算的分母
正确实现代码
写法1:全版本通用兼容写法
所有SQL数据库都支持该写法,通过子查询提前计算全表总记录数:
SELECT name, COUNT(name) AS count, -- 乘1.0是为了兼容部分数据库整数除法取整的问题 COUNT(name) * 1.0 / (SELECT COUNT(*) FROM 你的真实表名) AS rate FROM 你的真实表名 GROUP BY name;
写法2:窗口函数简洁写法
支持SQL:2003标准的数据库(MySQL8.0+、PostgreSQL、SQL Server、Oracle等)可以用窗口函数实现,不需要嵌套子查询:
SELECT DISTINCT name, COUNT(name) OVER (PARTITION BY name) AS count, COUNT(name) OVER (PARTITION BY name) * 1.0 / COUNT(*) OVER () AS rate FROM 你的真实表名;
两种写法返回结果完全匹配预期,Amit、Harsh的count为1、rate为0.25,Priya的count为2、rate为0.5。
内容的提问来源于stack exchange,提问作者user19398783
相关产品推荐
相关产品推荐

