计算一些特殊情况的查询
Calculate query with some special case
我有一个table
- 考试(studentID、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 is the average score of the student i^th with i=1…M where M is the total number of students
N is the total number of subjects.
The average score of the student s_i can be calculated by:
Where x_(i,k) is the last exam’s score of the student s_i on the subjectk^th. The last exam’s score means: student may retake the exam, and only the final result will be involved into the average score calculation.
The x_(i,k) may receive Null value if student s_i did not take exam on subject k^th.
我只能做类似的事情
select studentID, sum(examScore)/count(subjectCode) from Exam group by studentID
下半年如何处理这些特殊情况的问题?
据我了解你的问题,你想要每个学生的平均值,只考虑每个科目的最新分数。如果是,可以使用window函数进行过滤,然后聚合:
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
不同学生和科目的列表,然后将 table 与 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
在现实生活中,您可能有单独的引用 table 来存储学生和科目,您将使用它们来代替 select distinct
_ 子查询。
我有一个table
- 考试(studentID、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 is the average score of the student i^th with i=1…M where M is the total number of students N is the total number of subjects. The average score of the student s_i can be calculated by:
Where x_(i,k) is the last exam’s score of the student s_i on the subjectk^th. The last exam’s score means: student may retake the exam, and only the final result will be involved into the average score calculation. The x_(i,k) may receive Null value if student s_i did not take exam on subject k^th.
我只能做类似的事情
select studentID, sum(examScore)/count(subjectCode) from Exam group by studentID
下半年如何处理这些特殊情况的问题?
据我了解你的问题,你想要每个学生的平均值,只考虑每个科目的最新分数。如果是,可以使用window函数进行过滤,然后聚合:
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
不同学生和科目的列表,然后将 table 与 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
在现实生活中,您可能有单独的引用 table 来存储学生和科目,您将使用它们来代替 select distinct
_ 子查询。