学生重复课程的最大值 Grade_points

Max Grade_points for Repeated Course by Student

我正在从事一个学生注册数据库项目。学生注册课程并获得成绩。有时,学生重修一门课程并获得更好的成绩。我需要仅使用最好的成绩来计算 grade_point 和学分的总和。因此,对于每个在不同学期重复课程的学生,我必须确定最高成绩是多少。 emplid代表学生,course_id标识一门课程,credit是学分hr当然,Grade_point是字母成绩的数值,term代表学期。

这是我正在尝试完成的示例。

emplid couse_id credit_hr grade_pt term    
  0001    6001       3        4      Fall15 
  0001    6002       3       3.5     Fall15
  0001    6003       3        2      Fall15
  0001    6004       4       2.5     Sp16
  0001    6002       3       3.0     Sp16 
total(requirrd)      13      12

OP 评论中的示例代码:

SELECT a.emplid
      ,a.subject
      ,a.CATALOG_NBR
      ,a.strm
      ,a.CRSE_GRADE_OFF
      ,a.R‌​EPEAT_CANDIDATE
      ,a.un‌​t_taken AS cr
      ,a.CRSE_ID
      ,MAX(a.grade_points)
 OVER (PARTITION BY A.emplid ,crse_id) 
 FROM ps_CLASS_TBL_SE_VW a
 WHERE emplid LIKE '06381313011%'

这是一种方法。

问题很复杂,因为 - 看起来 - 你想显示结果集中的所有输入行,但是各种聚合应该只考虑一些行。

第一部分很简单:子查询对 EMPLIDCOURSE_ID 的每个组合的行进行排序,按收到的成绩降序排列,并根据以下条件为它们分配一个行号(在组内)那个顺序。

外部查询进行聚合。我使用 GROUP BY ROLLUP,它具有很大的灵活性。当 "rollup" 实际上是每一行时,我会显示该行的实际学分和成绩点,但在汇总中,我会总结其他内容:即学分(以及学分乘以成绩点)当行号为 1 时,否则为 NULL(在计算 SUM() 时被视为不存在)。

我创建了第二名员工,他在同一门课程中两次获得相同的分数(因此我可以检查我的解决方案在这种情况下是否给出错误答案)。我为每个课程 ID 模拟了一个单独的 table 学分,并且需要连接才能在结果中得到它。另外,我不对成绩点求和,因为成绩点计算不是这样做的;相反,我使用正确的计算方法,每个成绩点乘以课程小时数,然后将这些乘积(仅针对每门课程的最高成绩,分别针对每个 EMPLID)相加。

with
     grades ( emplid, course_id, grade_pt, term ) as (
       select '0001', '6001', 4  , 'Fall15' from dual union all
       select '0001', '6002', 3.5, 'Fall15' from dual union all
       select '0001', '6003', 2  , 'Fall15' from dual union all
       select '0001', '6004', 2.5, 'Sp16'   from dual union all
       select '0001', '6002', 3  , 'Sp16'   from dual union all
       select '0003', '6002', 3.5, 'Sp16'   from dual union all
       select '0003', '6003', 2.5, 'Fall16' from dual union all
       select '0003', '6003', 2.5, 'Sp15'   from dual
     ),
     credits ( course_id, credit_hr ) as (
       select '6001', 3 from dual union all
       select '6002', 3 from dual union all
       select '6003', 3 from dual union all
       select '6004', 4 from dual
     )
-- End of simulated inputs (for testing purposes only, not part of the solution).
-- SQL query begins BELOW THIS LINE.
select emplid, course_id,
       case when grouping(term) = 0 then credit_hr
            else sum(case when rn = 1 then credit_hr end) end as credit_hr,
       case when grouping(term) = 0 then grade_pt
            else sum(case when rn = 1 then credit_hr * grade_pt end)
                                                          end as total_grade_pt,
       term
from   ( select g.emplid, g.course_id, c.credit_hr, g.grade_pt, g.term,
                row_number() over (partition by g.emplid, g.course_id 
                                   order by g.grade_pt desc) as rn
         from   grades g join credits c on g.course_id = c.course_id
       )
group by rollup(emplid, course_id, credit_hr, grade_pt, term)
having grouping(term) = 0 or (grouping(course_id) = 1 and grouping(emplid) = 0)
;

输出:

EMPLID  COURSE_ID  CREDIT_HR  TOTAL_GRADE_PT  TERM
------  ---------  ---------  --------------  ------
0001    6001               3               4  Fall15
0001    6002               3               3  Sp16
0001    6002               3             3.5  Fall15
0001    6003               3               2  Fall15
0001    6004               4             2.5  Sp16
0001                      13            38.5
0003    6002               3             3.5  Sp16
0003    6003               3             2.5  Sp15
0003    6003               3             2.5  Fall16
0003                       6              18

select emplid, sum(credit_hr), sum(grade_pt)
from (
select emplid, course_id, credit_hr, grade_pt, term,
row_number() over(partition by emplid, course_id
order by grade_pt desc) rn
from your_table
)
where rn = 1
group by emplid