检索最高的两个分数

时间:2016-11-05 07:07:48

标签: sql ms-access

要计算考试的平均分,我需要得到以下结果:

subject1 + subject 2 + subject3 +(主题4,5,6的最佳2分之和)+(主题7,8,9,10,11中最佳2分)

部分科目将为null,因为学生只接受7,8,9,10,11

中的任何3项

每项考试都由ExamDateID

定义

我如何实现这一目标? (我需要结果来填充新表...不是这个问题的范围)

Access 2010

Main table

2 个答案:

答案 0 :(得分:4)

考虑在最终查询中使用三个源查询。请注意,在相同的 ExamDateID 主题范围内的标记将在计算中总结:

  1. 主题1-3的考试成绩(使用条件聚合)

    SELECT e.StudentID, e.ExamDateID, 
           SUM(IIF(e.Subject BETWEEN 1 AND 3, e.Marks, NULL)) AS SumMarks123
    FROM ExamTable AS e
    GROUP BY e.StudentID, e.ExamDateID;
    
  2. 主题4-6考试成绩(最高两名)(使用子查询)

    SELECT e.StudentID, e.ExamDateID, SUM(e.Marks) AS SumTop2Marks456
    FROM ExamTable AS e
    WHERE e.Subject BETWEEN 4 AND 6 
    AND  (SELECT Count(*) FROM ExamTable sub
          WHERE sub.StudentID = e.StudentID AND sub.ExamDateID = e.ExamDateID
          AND sub.Subject BETWEEN 4 AND 6 AND sub.Marks >= e.Marks)  <= 2
    GROUP BY e.StudentID, e.ExamDateID;
    
  3. 主题的考试成绩7-11(最高的两个)(使用子查询)

    SELECT e.StudentID, e.ExamDateID, SUM(e.Marks) AS SumTop2Marks711
    FROM ExamTable AS e
    WHERE e.Subject BETWEEN 7 AND 11
    AND  (SELECT Count(*) FROM ExamTable sub
          WHERE sub.StudentID = e.StudentID AND sub.ExamDateID = e.ExamDateID
          AND sub.Subject BETWEEN 7 AND 11 AND sub.Marks >= e.Marks)  <= 2
    GROUP BY e.StudentID, e.ExamDateID;
    
  4. 最终查询

    SELECT a.StudentID, a.ExamDateID, 
           (a.SumMarks123 + b.SumTop2Marks456 + c.SumTop2Marks711) As SumScore
    FROM (ExamAvgSubj123Q a 
    INNER JOIN ExamAvgSubj456Q b 
        ON (a.ExamDateID = b.ExamDateID) AND (a.StudentID = b.StudentID)) 
    INNER JOIN ExamAvgSubj711Q c 
        ON (a.ExamDateID = c.ExamDateID) AND (a.StudentID = c.StudentID);
    

    当然没有理由,你不能将所有查询合并为一个,但是看到使用派生表维护时可能有点紧张:

    SELECT a.StudentID, a.ExamDateID, 
           (a.SumMarks123 + b.SumTop2Marks456 + c.SumTop2Marks711) As SumScore    
    FROM
       ((SELECT e.StudentID, e.ExamDateID, 
                SUM(IIF(e.Subject BETWEEN 1 AND 3, e.Marks, NULL)) AS SumMarks123
        FROM ExamTable AS e
        GROUP BY e.StudentID, e.ExamDateID) a 
    
    INNER JOIN 
      (SELECT e.StudentID, e.ExamDateID, SUM(e.Marks) AS SumTop2Marks456
       FROM ExamTable AS e
       WHERE e.Subject BETWEEN 4 AND 6 
       AND  (SELECT Count(*) FROM ExamTable sub
             WHERE sub.StudentID = e.StudentID AND sub.ExamDateID = e.ExamDateID
             AND sub.Subject BETWEEN 4 AND 6 AND sub.Marks >= e.Marks)  <= 2
       GROUP BY e.StudentID, e.ExamDateID) b 
    
    ON (a.ExamDateID = b.ExamDateID) AND (a.StudentID = b.StudentID)) 
    
    INNER JOIN 
      (SELECT e.StudentID, e.ExamDateID, SUM(e.Marks) AS SumTop2Marks711
       FROM ExamTable AS e
       WHERE e.Subject BETWEEN 7 AND 11
       AND  (SELECT Count(*) FROM ExamTable sub
             WHERE sub.StudentID = e.StudentID AND sub.ExamDateID = e.ExamDateID
             AND sub.Subject BETWEEN 7 AND 11 AND sub.Marks >= e.Marks)  <= 2
       GROUP BY e.StudentID, e.ExamDateID) c 
    
    ON (a.ExamDateID = c.ExamDateID) AND (a.StudentID = c.StudentID);
    

答案 1 :(得分:2)

编辑:添加了最佳两个分数

我建议您在button_click事件中使用VBA。以下是代码的概要。你需要改进它:

dim rs as DAO.recordset
dim db as dao.database
set db = current db
dim qry as string
dim avgScore as double
avgScore = 0
numberOfSubject = 0

dim firstBestScore2in3 as double, firstBestScore2in3 as double
firstBestScore2in3 = 0
secondBestScore2in3 = 0

dim firstBestScore2in5 as double, firstBestScore2in5 as double
firstBestScore2in5 = 0
secondBestScore2in5 = 0

'query your database
qry = _
"SELECT studentID, subject, marks " & _
"FROM exams " & _
"WHERE studentID = " & Me.txtStudentID & " " & _
"ORDER BY stubject;"
set rs = db.opendynaset qry

'Iterate through recordset
Do While Not rs.EOF Then

 Select Case rs!subject
  Case 1 To 3
   avgScore = avgScore + rs!subject
  Case 4 To 6
   if (rs!subject > firstBestScore2in3) then
     firstBestScore2in3 = rs!subject
   elseif (rs!subject > secondBestScore2in3) then
     secondBestScore2in3 = rs!subject
   end if
  Case 7 To 11
   if (rs!subject > firstBestScore2in5) then
     firstBestScore2in5 = rs!subject
   elseif (rs!subject > secondBestScore2in5) then
     secondBestScore2in5 = rs!subject
   end if
 end case

 rs.next
loop

avgScore = avgScore + firstBestScore2in3 + secondBestScore2in3 + firstBestScore2in5 + secondBestScore2in5

avgScore = avgScore / 7