Sql 给学生分配一个等级,并得到每个等级的总数

Sql 给学生分配一个等级,并得到每个等级的总数,sql,oracle,Sql,Oracle,我有下面的select语句。我有学校,课程,学生和分数1-100。我想分配一个a、B、C、D年级,然后得到每个年级的学生总数。我的结果只显示了每个分数的计数,而不是分数的计数 select schools.name as school_name, courses.name as course, CASE WHEN ((studentgrades.averageScore / 50 *

我有下面的select语句。我有学校,课程,学生和分数1-100。我想分配一个a、B、C、D年级,然后得到每个年级的学生总数。我的结果只显示了每个分数的计数,而不是分数的计数

select          
    schools.name as school_name,            
    courses.name as course,   
        CASE
             WHEN   ((studentgrades.averageScore / 50  * 100)  > 79)
                  THEN 'A' 
                  WHEN   ((studentgrades.averageScore / 50  * 100)  < 80) 
                         AND ((studentgrades.averageScore / 50  * 100)  >64)
                  THEN 'B' 
                  WHEN   ((studentgrades.averageScore / 50  * 100)  < 80) 
                         AND ((studentgrades.averageScore / 50  * 100)  >64)
                  THEN 'C' 
                  WHEN   ((studentgrades.averageScore / 50  * 100)  < 50)
                  THEN 'D'                         
          END as grade,             
    count(*)                 
from
    students,
    studentgrades,
    schools,
    courses
where
    studentgrades.studentid = students.studentid
    and studentgrades.schoolid = students.schoolid     
    and studentgrades.schoolid = schools.school_number 
    and courses.id = studentgrades.coursesid
    and studentgrades.averageScore is not null 
    and schools.name = 'St. Joe School'           
group by schools.name,  courses.name,standardsgrades.averageScore
我想看到的是A、B、C、D各等级的总数

School Name     Course        Grade     Count        
St. Joe School  MATH 30         A         30
St. Joe School  MATH 30         B         20
St. Joe School  MATH 30         C         10
St. Joe School  MATH 30         D         5

将查询放入视图中,然后使用另一个GROUP BY和SUM进行查询

SELECT SchoolName, Course, Grade, SUM(Count)
FROM YourNewView
GROUP BY SchoolName, Course, Grade

您需要按计算的分数分组,而不是按平均分数分组。您可以使用CTE、子查询或重复group子句中的整个表达式来执行此操作

我发现基于CTE的解决方案有点容易阅读:

with cte
as (
    select schools.name as school_name,
        courses.name as course,
        case when ((studentgrades.averageScore / 50 * 100) > 79) then 'A' when ((studentgrades.averageScore / 50 * 100) < 80)
                and ((studentgrades.averageScore / 50 * 100) > 64) then 'B' when ((studentgrades.averageScore / 50 * 100) < 80)
                and ((studentgrades.averageScore / 50 * 100) > 64) then 'C' when ((studentgrades.averageScore / 50 * 100) < 50) then 'D' end as grade
    from students
    join studentgrades on studentgrades.studentid = students.studentid
        and studentgrades.schoolid = students.schoolid
    join schools on studentgrades.schoolid = schools.school_number
        and studentgrades.schoolid = schools.school_number
    join courses on courses.id = studentgrades.coursesid
    where studentgrades.averageScore is not null
        and schools.name = 'St. Joe School'
    )
select school_name,
    course,
    grade,
    count(*)
from cte
group by school_name,
    course,
    grade;

另外,请始终使用现代的显式联接语法,而不是旧的基于逗号的联接。

只需在现有查询上选择,如下所示:

select school_name, course,
grade,
sum(grade)
(select          
schools.name as school_name,            
courses.name as course,   
    CASE
         WHEN   ((studentgrades.averageScore / 50  * 100)  > 79)
              THEN 'A' 
              WHEN   ((studentgrades.averageScore / 50  * 100)  < 80) 
                     AND ((studentgrades.averageScore / 50  * 100)  >64)
              THEN 'B' 
              WHEN   ((studentgrades.averageScore / 50  * 100)  < 80) 
                     AND ((studentgrades.averageScore / 50  * 100)  >64)
              THEN 'C' 
              WHEN   ((studentgrades.averageScore / 50  * 100)  < 50)
              THEN 'D'                         
      END as grade,             
count(*)                 
from
students,
studentgrades,
schools,
courses
where
studentgrades.studentid = students.studentid
and studentgrades.schoolid = students.schoolid     
and studentgrades.schoolid = schools.school_number 
and courses.id = studentgrades.coursesid
and studentgrades.averageScore is not null 
and schools.name = 'St. Joe School'           
group by schools.name,  courses.name,standardsgrades.averageScore)
group by grade order by grade;

为什么Oracle用户倾向于使用旧的隐式联接?我正试图修改一些旧代码。我通常使用显式连接;移除group by on,standardsgrades.averageScore,并通过{your case statement}将分区上的count*更改为count*。这很接近,但它显示的是原始表中Grade列的计数,而不是“count”列的总计数。因此,它计算了7行A,而不是5+3+2+1+1+2+3=17--------------------学校名称课程等级统计圣乔学校数学30 A7@EvilEddie-您自己的样本数据显示它应该是17。如果您需要任何进一步的帮助,请同时添加示例输入数据。对不起…注释框不允许使用良好的格式。返回的正确结果应该是第4列Count中前7行的总计17行,但我得到的结果是第3列Grade中前7行的总计7行。
select school_name, course,
grade,
sum(grade)
(select          
schools.name as school_name,            
courses.name as course,   
    CASE
         WHEN   ((studentgrades.averageScore / 50  * 100)  > 79)
              THEN 'A' 
              WHEN   ((studentgrades.averageScore / 50  * 100)  < 80) 
                     AND ((studentgrades.averageScore / 50  * 100)  >64)
              THEN 'B' 
              WHEN   ((studentgrades.averageScore / 50  * 100)  < 80) 
                     AND ((studentgrades.averageScore / 50  * 100)  >64)
              THEN 'C' 
              WHEN   ((studentgrades.averageScore / 50  * 100)  < 50)
              THEN 'D'                         
      END as grade,             
count(*)                 
from
students,
studentgrades,
schools,
courses
where
studentgrades.studentid = students.studentid
and studentgrades.schoolid = students.schoolid     
and studentgrades.schoolid = schools.school_number 
and courses.id = studentgrades.coursesid
and studentgrades.averageScore is not null 
and schools.name = 'St. Joe School'           
group by schools.name,  courses.name,standardsgrades.averageScore)
group by grade order by grade;