2017-08-01 60 views
0

我正在參與學生註冊數據庫項目。學生參加課程並獲得成績。有時候學生會重複一門課程並獲得更好的成績。我只需要使用最好的等級來計算grade_point和credit的總和。所以對於重複不同學期課程的每個學生,我必須確定最高成績是什麼。 emplid代表學生,course_id代表課程,credit當然是學分hr,grade_point是字母等級的數字值,術語代表學期會話。學生重複課程的最高Grade_points

這是我正在努力完成的一個例子。從OP的評論

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 

示例代碼:

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%' 
+1

確定。你有什麼嘗試? – OldProgrammer

+0

快速提問:學分課程是學習時間的一個特點,無論學生是誰,也不管學期是在哪裏學習的。如果這是正確的(我的整個職業生涯都是在學術界),那麼爲什麼它是本表中的專欄,而不是單獨的表格中提供有關課程的信息? – mathguy

+0

@mathguy你對我創建視圖根據我的需求。 – saqib

回答

-1

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

3

下面是做到這一點的方法之一。

問題很複雜,因爲 - 看起來 - 您想要在結果集中顯示所有輸入行,但各種聚合應該只考慮一些行。

第一部分很簡單:子查詢按照接收等級的降序對EMPLIDCOURSE_ID的每個組合的行進行排序,並根據該順序爲它們分配一個行號(在組內)。

外部查詢執行聚合。我使用GROUP BY ROLLUP,這允許很大的靈活性。當「彙總」實際上是每一行本身時,我會顯示該行的實際信用小時數和等級點數,但是在總計中,我總結了其他一些信息:即在信用時間(以及信用小時乘以等級點數)當行號爲1時,以及NULL,否則(在計算SUM()時將其視爲不存在)。

我創建了第二個員工,他在同一個課程中獲得了兩次相同的分數(所以我可以檢查我的解決方案在這種情況下不會給出錯誤答案)。我爲每個課程ID的學分模擬了一個單獨的表格,並且在結果中需要連接。另外,我不總結分數點數,因爲這不是用分數點計算完成的;相反,我使用正確的計算方法,每個成績點乘以課程時數,然後將這些產品(僅適用於每門課程的最高成績,各自分別爲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 
+0

是的,這個邏輯也有效;) – saqib