2017-04-20 123 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