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