Oracle - 获取最佳结果的最新子集

时间:2013-07-23 12:20:18

标签: sql oracle

我有一张考试成绩表如下:

CREATE TABLE tbl (
studentid INT,
examid INT,
score INT,
attempt INT,
percentcorrect INT
);

现在,每个学生都需要提取他的最佳考试成绩(按百分比校正),如果考试已经完成两次,给定学生的最佳分数相同,则应显示最新尝试的记录。我已经用双嵌套查询完成了它(首先选择最高百分比校正,然后从结果集中选择最大尝试,然后是其余数据),但我希望有更有效的方法来实现这一点。有什么想法吗?

编辑: 我的问题:

SELECT 
    result.score
    , r2.attempt
    , r2.percentcorrect
    , r2.studentid
    , r2.examid
FROM
    tbl result JOIN
    (
        SELECT
            res.studentid
            , res.examid
            , r.percentcorrect
            , MAX(res.attempt) AS attempt
        FROM 
            tbl res JOIN
            (
                SELECT studentid, examid, MAX(percentcorrect) AS percentcorrect
                FROM tbl
                GROUP BY studentid, examid
            ) r ON r.studentid = res.studentid 
            AND r.examid = res.examid
            AND r.percentcorrect = res.percentcorrect
        GROUP BY
            res.studentid
            , res.examid
            , r.percentcorrect
        ORDER BY res.examid
      ) r2
ON r2.studentid = result.studentid
AND r2.examid = result.examid
AND r2.percentcorrect = result.percentcorrect
AND r2.attempt = result.attempt

一些示例数据:

INSERT ALL 
INTO tbl(studentid, examid, percentcorrect, attempt, score)
VALUES(1,1,30,1,10)
INTO tbl(studentid, examid, percentcorrect, attempt, score)
VALUES(1,1,20,2,15)
INTO tbl(studentid, examid, percentcorrect, attempt, score)
VALUES(2,1,80,1,100)
INTO tbl(studentid, examid, percentcorrect, attempt, score)
VALUES(2,1,80,2,90)
INTO tbl(studentid, examid, percentcorrect, attempt, score)
VALUES(3,2,10,1,9)
INTO tbl(studentid, examid, percentcorrect, attempt, score)
VALUES(3,3,15,1,100)
SELECT * FROM DUAL; COMMIT;

3 个答案:

答案 0 :(得分:4)

Analytical RANK function可用于此:

SELECT studentid, examid, score
FROM (
  SELECT
    studentid,
    examid,
    score,
    attempt,
    RANK() OVER (
      PARTITION BY studentid, examid
      ORDER BY score DESC, attempt DESC) AS ScoreAttemptRank
  FROM tbl
)
WHERE ScoreAttemptRank = 1

此查询将返回每位学生/每次考试的最新尝试的最佳分数。如果您只需要每个学生的最佳考试成绩而不考虑考试,请将PARTITION BY studentid, examid更改为PARTITION BY studentid

答案 1 :(得分:0)

您可以使用Comman Table Expression(https://forums.oracle.com/thread/921467)和OVER(http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions137.htm)来实现结果。下面的查询是w.r.t SQL Server,我们在Oracle中也有相同的东西。另外,为了确定同一考试的最新考试成绩,我在表格中有ExamDate

;WITH    CTE_StudentResult
          AS ( SELECT   StudentId ,
                        PercentCorrect ,
                        ROW_NUMBER() OVER ( PARTITION BY StudentId ORDER BY percentcorrect DESC, ExamDate DESC ) AS RowNumber
               FROM     tbl
             )
    SELECT  StudentId ,
            PercentCorrect
    FROM    CTE_StudentResult
    WHERE   RowNumber = 1

答案 2 :(得分:0)

试试这个

SELECT DISTINCT * FROM tbl
WHERE (studentid, percentcorrect, attempt) IN (
        SELECT   studentid, percentcorrect, MAX (attempt)
        FROM tbl
        WHERE (studentid, percentcorrect) IN (SELECT   studentid,MAX (percentcorrect)FROM tbl GROUP BY studentid)
        GROUP BY studentid, percentcorrect)