如何使用SQL语句计算百分比

时间:2009-04-21 00:16:29

标签: sql sql-server tsql

我有一个SQL Server表,其中包含用户和&他们的成绩。为简单起见,我们只想说有两列 - name& grade。所以一个典型的行是Name:“John Doe”,等级:“A”。

我正在寻找一个可以找到所有可能答案百分比的SQL语句。 (A,B,C等......)另外,有没有办法在没有定义所有可能的答案的情况下这样做(开放文本字段 - 用户可以输入'通过/失败','无'等等)< / p>

我正在寻找的最终输出是A:5%,B:15%,C:40%等......

13 个答案:

答案 0 :(得分:194)

我测试了以下内容,这确实有效。 gordyii的答案很接近但在错误的地方乘以100并且有一些缺失的括号。

Select Grade, (Count(Grade)* 100 / (Select Count(*) From MyTable)) as Score
From MyTable
Group By Grade

答案 1 :(得分:178)

  1. 效率最高(使用over())。

    select Grade, count(*) * 100.0 / sum(count(*)) over()
    from MyTable
    group by Grade
    
  2. Universal(任何SQL版本)。

    select Rate, count(*) * 100.0 / (select count(*) from MyTable)
    from MyTable
    group by Rate;
    
  3. 使用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;
    

答案 2 :(得分:34)

您可以使用没有“partition by”子句的窗口函数,而不是使用单独的CTE来获取总数。

如果您正在使用:

count(*)

获取组的计数,您可以使用:

sum(count(*)) over ()

获得总数。

例如:

select Grade, 100. * count(*) / sum(count(*)) over ()
from table
group by Grade;

我的体验往往更快,但我认为在某些情况下它可能会在内部使用临时表(我在使用“set statistics io on”运行时看到“工作表”)。

修改 我不确定我的示例查询是否是您要查找的内容,我只是说明了窗口函数的工作方式。

答案 3 :(得分:9)

您必须计算成绩总数 如果是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

答案 4 :(得分:9)

您需要在成绩字段上进行分组。这个查询应该可以在几乎任何数据库中为您提供所需的内容。

    Select Grade, CountofGrade / sum(CountofGrade) *100 
    from
    (
    Select Grade, Count(*) as CountofGrade
    From Grades
    Group By Grade) as sub
    Group by Grade

您应该指定您正在使用的系统。

答案 5 :(得分:7)

我只需要使用它,我需要计算一个百分比..

ROUND(CAST((Numerator * 100.0 / Denominator) AS FLOAT), 2) AS Percentage

请注意,100.0会返回小数,而100就会自动将结果四舍五入到最接近的整数,即使使用ROUND()函数也是如此!

答案 6 :(得分:5)

以下内容应该有效

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

答案 7 :(得分:5)

我相信这是一个通用解决方案,尽管我使用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 - 算术;请参阅注释,并感谢迅雷。)

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');

答案 8 :(得分:4)

SELECT Grade, GradeCount / SUM(GradeCount)
FROM (SELECT Grade, COUNT(*) As GradeCount
      FROM myTable
      GROUP BY Grade) Grades

答案 9 :(得分:3)

在任何sql server版本中,您可以使用变量作为所有等级的总和,如下所示:

declare @countOfAll decimal(18, 4)
select @countOfAll = COUNT(*) from Grades

select
Grade,  COUNT(*) / @countOfAll * 100
from Grades
group by Grade

答案 10 :(得分:3)

您可以在自己的查询中使用子选择(未经测试但不确定哪个更快):

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

答案 11 :(得分:0)

我有与此类似的问题。您应该能够得到正确的结果乘以1.0而不是100。请参阅示例图片

选择成绩,将(Count(Grade)* 1.0 /(从MyTable中选择Count(*))作为MyTable中的得分)按等级分组 See reference image attached

答案 12 :(得分:0)

这在MS SQL中运行良好。它将varchar转换为两个小数位数限制的float的结果。

Select field1, cast(Try_convert(float,(Count(field2)* 100) / 
Try_convert(float, (Select Count(*) From table1))) as decimal(10,2)) as new_field_name 
From table1 
Group By field1, field2;