如何用SQL语句计算百分比
我有一个包含用户及其成绩的SQL Server表。 为了简单起见,我们只是说有2列 – name
和grade
。 所以一个典型的行将是名字:“John Doe”,等级:“A”。
我正在寻找一个SQL语句,可以find所有可能的答案的百分比。 (A,B,C等)另外,有没有办法做到这一点,没有定义所有可能的答案(打开文本字段 – 用户可以input“通过/失败”,“没有”等…)
我要找的最后输出是A:5%,B:15%,C:40%等等。
我已经testing了以下,这是行不通的。 gordyii的答案很接近,但在错误的地方增加了100,并且有一些缺失的括号。
Select Grade, (Count(Grade)* 100 / (Select Count(*) From MyTable)) as Score From MyTable Group By Grade
-
最高效的(使用over())。
select Grade, count(*) * 100.0 / sum(count(*)) over() from MyTable group by Grade
-
通用(任何SQL版本)。
select Rate, count(*) * 100.0 / (select count(*) from MyTable) from MyTable group by Rate;
-
使用CTE,效率最低。
with t(Rate, RateCount) as ( select Rate, count(*) from MyTable group by Rate ) select Rate, RateCount * 100.0/(select sum(RateCount) from t) from t;
不用单独的CTE来获得总数,你可以使用一个没有“partition by”子句的窗口函数。
如果您正在使用:
count(*)
为了得到一个组的计数,你可以使用:
sum(count(*)) over ()
得到总数。
例如:
select Grade, 100. * count(*) / sum(count(*)) over () from table group by Grade;
我的经验往往会更快,但我认为在某些情况下可能会在内部使用临时表(我已经在“set statistics io on”下运行时看到了“Worktable”)。
编辑:我不知道如果我的示例查询是你在找什么,我只是说明窗口function是如何工作的。
你必须计算总分数如果是SQL 2005,你可以使用CTE
WITH Tot(Total) ( SELECT COUNT(*) FROM table ) SELECT Grade, COUNT(*) / Total * 100 --, CONVERT(VARCHAR, COUNT(*) / Total * 100) + '%' -- With percentage sign --, CONVERT(VARCHAR, ROUND(COUNT(*) / Total * 100, -2)) + '%' -- With Round FROM table GROUP BY Grade
你需要在成绩栏上分组。 这个查询应该给你几乎所有的数据库。
Select Grade, CountofGrade / sum(CountofGrade) *100 from ( Select Grade, Count(*) as CountofGrade From Grades Group By Grade) as sub Group by Grade
你应该指定你正在使用的系统。
我相信这是一个通用的解决scheme,尽pipe我使用IBM Informix Dynamic Server 11.50.FC3进行了testing。 以下查询:
SELECT grade, ROUND(100.0 * grade_sum / (SELECT COUNT(*) FROM grades), 2) AS pct_of_grades FROM (SELECT grade, COUNT(*) AS grade_sum FROM grades GROUP BY grade ) ORDER BY grade;
在横向规则下面显示的testing数据上给出以下输出。 ROUND
函数可能是DBMS特定的,但其余(可能)不是。 (请注意,我将100更改为100.0,以确保使用非整数进行计算 – DECIMAL,NUMERIC – arithmetic;请参阅评论,感谢Thunder。)
grade pct_of_grades CHAR(1) DECIMAL(32,2) A 32.26 B 16.13 C 12.90 D 12.90 E 9.68 F 16.13
CREATE TABLE grades ( id VARCHAR(10) NOT NULL, grade CHAR(1) NOT NULL CHECK (grade MATCHES '[ABCDEF]') ); INSERT INTO grades VALUES('1001', 'A'); INSERT INTO grades VALUES('1002', 'B'); INSERT INTO grades VALUES('1003', 'F'); INSERT INTO grades VALUES('1004', 'C'); INSERT INTO grades VALUES('1005', 'D'); INSERT INTO grades VALUES('1006', 'A'); INSERT INTO grades VALUES('1007', 'F'); INSERT INTO grades VALUES('1008', 'C'); INSERT INTO grades VALUES('1009', 'A'); INSERT INTO grades VALUES('1010', 'E'); INSERT INTO grades VALUES('1001', 'A'); INSERT INTO grades VALUES('1012', 'F'); INSERT INTO grades VALUES('1013', 'D'); INSERT INTO grades VALUES('1014', 'B'); INSERT INTO grades VALUES('1015', 'E'); INSERT INTO grades VALUES('1016', 'A'); INSERT INTO grades VALUES('1017', 'F'); INSERT INTO grades VALUES('1018', 'B'); INSERT INTO grades VALUES('1019', 'C'); INSERT INTO grades VALUES('1020', 'A'); INSERT INTO grades VALUES('1021', 'A'); INSERT INTO grades VALUES('1022', 'E'); INSERT INTO grades VALUES('1023', 'D'); INSERT INTO grades VALUES('1024', 'B'); INSERT INTO grades VALUES('1025', 'A'); INSERT INTO grades VALUES('1026', 'A'); INSERT INTO grades VALUES('1027', 'D'); INSERT INTO grades VALUES('1028', 'B'); INSERT INTO grades VALUES('1029', 'A'); INSERT INTO grades VALUES('1030', 'C'); INSERT INTO grades VALUES('1031', 'F');
以下应该工作
ID - Key Grade - A,B,C,D...
编辑:移动* 100
并添加1.0
以确保它不会做整数除法
Select Grade, Count(ID) * 100.0 / ((Select Count(ID) From MyTable) * 1.0) From MyTable Group By Grade
当我需要制定一个百分比时,我只是简单地使用它。
ROUND(CAST((Numerator * 100.0 / Denominator) AS FLOAT), 2) AS Percentage
请注意,100.0返回小数,而100自己会将结果四舍五入到最接近的整数,即使使用ROUND()函数!
在任何sql服务器版本中,你都可以使用一个variables作为所有成绩的总和,如下所示:
declare @countOfAll decimal(18, 4) select @countOfAll = COUNT(*) from Grades select Grade, COUNT(*) / @countOfAll * 100 from Grades group by Grade
您可以在您的查询中使用子查询(未经testing,不确定哪个更快):
SELECT Grade, COUNT(*) / TotalRows FROM (SELECT Grade, COUNT(*) As TotalRows FROM myTable) Grades GROUP BY Grade, TotalRows
要么
SELECT Grade, SUM(PartialCount) FROM (SELECT Grade, 1/COUNT(*) AS PartialCount FROM myTable) Grades GROUP BY Grade
要么
SELECT Grade, GradeCount / SUM(GradeCount) FROM (SELECT Grade, COUNT(*) As GradeCount FROM myTable GROUP BY Grade) Grades
您也可以使用存储过程(对Firebird语法表示歉意):
SELECT COUNT(*) FROM myTable INTO :TotalCount; FOR SELECT Grade, COUNT(*) FROM myTable GROUP BY Grade INTO :Grade, :GradeCount DO BEGIN Percent = :GradeCount / :TotalCount; SUSPEND; END
SELECT Grade, GradeCount / SUM(GradeCount) FROM (SELECT Grade, COUNT(*) As GradeCount FROM myTable GROUP BY Grade) Grades