Answers:
我已经测试了以下内容,这确实可行。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 Grade, count(*) * 100.0 / (select count(*) from MyTable)
from MyTable
group by Grade;
使用CTE,效率最低。
with t(Grade, GradeCount)
as
(
select Grade, count(*)
from MyTable
group by Grade
)
select Grade, GradeCount * 100.0/(select sum(GradeCount) from t)
from t;
cast((count(*) / (sum(count(*)) over() / 100)) AS DECIMAL(18, 2)) as Percentage
over()
可以在Postgresql 10上很好地工作
您可以使用不带“ partition by”子句的窗口函数来代替使用单独的CTE来获取总数。
如果您正在使用:
count(*)
要获取组的计数,可以使用:
sum(count(*)) over ()
得到总数。
例如:
select Grade, 100. * count(*) / sum(count(*)) over ()
from table
group by Grade;
根据我的经验,它通常会更快,但是我认为在某些情况下它可能会在内部使用临时表(在“ set statistics io on”下运行时,我已经看到“ Worktable”)。
编辑: 我不确定我的示例查询是否是您要寻找的,我只是在说明开窗函数的工作方式。
tempdb
工作台所在的线轴。逻辑读值似乎更高,但计算方式却与正常情况不同
COUNT(*) OVER ()
查询中的会返回一个完全不相关的数字(特别是分组结果集的行数)。您应该SUM(COUNT(*)) OVER ()
改用。
您必须计算成绩的总和。如果是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
您应该指定您正在使用的系统。
每当我需要计算百分比时,我都会简单地使用它。
ROUND(CAST((Numerator * 100.0 / Denominator) AS FLOAT), 2) AS Percentage
请注意,即使使用ROUND()函数,100.0也会返回小数,而单独使用100会将结果四舍五入到最接近的整数!
以下应该工作
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
我相信这是一个通用的解决方案,尽管我使用IBM Informix Dynamic Server 11.50.FC3对其进行了测试。以下查询:
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;
在水平线下方显示的测试数据上提供以下输出。该ROUND
功能可能是特定于DBMS的,而其余功能(可能)不是。(请注意,我将100更改为100.0,以确保使用非整数-DECIMAL,NUMERIC-算术进行计算;请参见注释,并感谢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');
您可以在from查询中使用子选择(未经测试,不确定哪个更快):
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
我有与此类似的问题。您应该能够得到正确的结果乘以1.0而不是100。请参阅示例图像
选择成绩,将(Count(Grade)* 1.0 /(从MyTable中选择Count(*)))作为MyTable中的得分按等级分组