计算特殊情况下的查询

时间:2020-11-04 11:10:16

标签: sql sql-server average aggregate-functions greatest-n-per-group

我有一张桌子

  • 考试(学生ID,subjectCode,examDate,examScore)

以及许多类似的值

INSERT [dbo].[Exam] ([studentID], [subjectCode], [examDate], [examScore]) VALUES (N'ST01', N'PRJ', CAST(0x253C0B00 AS Date), 5)
INSERT [dbo].[Exam] ([studentID], [subjectCode], [examDate], [examScore]) VALUES (N'ST01', N'WIG', CAST(0x253C0B00 AS Date), 1)
 . . .
INSERT [dbo].[Exam] ([studentID], [subjectCode], [examDate], [examScore]) VALUES (N'ST09', N'WIG', CAST(0x253C0B00 AS Date), 4)
INSERT [dbo].[Exam] ([studentID], [subjectCode], [examDate], [examScore]) VALUES (N'ST09', N'WIG', CAST(0x263C0B00 AS Date), 9)
INSERT [dbo].[Exam] ([studentID], [subjectCode], [examDate], [examScore]) VALUES (N'ST10', N'MAD', CAST(0x253C0B00 AS Date), 3)
INSERT [dbo].[Exam] ([studentID], [subjectCode], [examDate], [examScore]) VALUES (N'ST10', N'MAE', CAST(0x253C0B00 AS Date), 4) 

我必须计算出所有学生的平均分数,以便:(对不起,这很糟糕)

s_i是学生i ^ th的平均分数,其中i = 1…M,其中M是学生总数 N是主体总数。 可以通过以下方式计算学生s_i的平均分数:

enter image description here

其中x_(i,k)是学生s_i在主题上的最后一次考试的分数。 上次考试的分数表示:学生可以重新参加考试,并且只有最终结果会被纳入平均分数计算中。 如果学生s_i没有参加第k个主题的考试,则x_(i,k)可能会收到Null值。

enter image description here

我只能做类似的事情

select studentID, sum(examScore)/count(subjectCode) from Exam group by studentID

下半年如何处理这些特殊情况的问题?

1 个答案:

答案 0 :(得分:1)

据我所知,您想要的是每个学生的平均成绩,只考虑每个学科的最新分数。如果是这样,您可以使用窗口函数进行过滤,然后进行聚合:

select studentid, avg(examscore) avgscore
from (
    select e.*, 
        row_number() over(partition by studentid, subjectcode order by examdate desc) rn
    from exam e
) e
where rn = 1
group by studentid

如果您想将“缺失的”主题计为0,则要复杂一些。通常,您将cross join列出不同的学生和科目,然后在表中插入left join

select st.studentid, avg(coalesce(e.examscore, 0)) avgscore
from (select distinct studentid from exam) st
cross join (select distinct subjectcode from exam) su
left join (
    select e.*, 
        row_number() over(partition by studentid, subjectcode order by examdate desc) rn
    from exam e
) e 
    on  e.studentid   = st.studentid 
    and e.subjectcode = su.subjectcode 
    and e.rn = 1
group by st.studentid

在现实生活中,您可能会有单独的参照表来存储学生和学科,您将使用它们代替select distinct _子查询。

相关问题