2017-04-20 151 views
-1

假設我有以下表格:計算平均爲每個學生

- 表學生

create table Student(
num int primary key identity, 
firstName varchar(30) not null, 
lastName varchar(30) 
) 

- 表模塊

create table Module(
code int primary key identity, 
name varchar(30) not null, 
coefficient int not null) 

- 表符號

create table Notation(
stud int references student, 
Mod int references Module, 
DateExam datetime default getdate(), 
Note float check (Note between 0 and 20) 
primary key(stud , Mod)) 

我想要的是顯示學生姓名,學生人數和平均數,從最好到最差。

更新:

平均=總和(NI * CI)/和(CI); c:係數。 N:注意

+1

平均的什麼? – JohnHC

+1

他們的號碼是多少? – Lamak

+0

我不認爲你想使用NOTE作爲一個浮點數。十進制(x,y)可能會更好(取決於您要跟蹤的小數位數) – xQbert

回答

2

這得到兩個音符爲每個模塊中每個學生,他們的平均在所有模塊

select s1.FirstName, s1.LastName, m2.name as module_name, n3.Note, x1.av_note 
from student s1 
left join notation n3 
    on n3.stud = s1.num 
left join module m2 
    on m2.code = n3.mod 
left join 
(
select stud, avg(note) as av_note 
from notation 
group by stud 
) x1 
    on s1.num = x1.stud 
order by av_note, lastname desc 
+0

這會排除所有沒有筆記的學生。我們不應該保留那些;但對數據庫的無窗口功能很好! :P – xQbert

+0

@xQbert我在想...左編輯編輯 – JohnHC

2

不要以爲你需要的模塊。這假定筆記是你想要平均的字段。

SELECT FirstName, LastName, Note, avg(note) over (partition by s.Num) AvgNote 
FROM Student S 
LEFT JOIN Notation N 
on S.Num = N.Stud 
GROUP BY FirstName, LastName, S.Num 
ORDER BY as AvgNote Desc 

另外,當處理成績時,作爲數據類型浮動是一個壞主意。浮點設計不精確以支持較小的數據存儲空間。這並不重要,當你處理科學記數法時,精度不是必需的,但在這種情況下,我認爲小數點是一個更好的選擇。

+0

我總是忘記窗口函數... – JohnHC

+0

他們很強大。我不確定Module上有什麼係數,所以我們可能需要它... – xQbert

0

這裏是我的解決方案:

select tab.num,tab.firstName, sum(noteMultiCoef)/sum(coefficient) as average from 
    (select st.num,st.firstName, coefficient, note*coefficient as noteMultiCoef 
    from notation nt, student st, Module md 
    where st.num= nt.stud 
    and nt.code = md.mod) tab 
    group by tab.num, tab.firstName 
    order by average desc