0

我有一个名为等级的表。名为“学生、实用、书面”的列。我试图找出考试总分排名前 5 位的学生。以下是我不确定如何正确加入它们的查询。我正在使用 oracle 11g。这让我得到了每个学生的总金额:

SELECT Student, Practical, Written, (Practical+Written) AS SumColumn 
FROM Grades;

这将获得前 5 名的学生:

SELECT Student 
FROM ( SELECT Student,
              , DENSE_RANK() OVER (ORDER BY Score DESC) as Score_dr
       FROM Grades ) 
WHERE Student_dr <= 5
order by Student_dr;
4

3 回答 3

0

我更喜欢的方法是以数据为中心,而不是以行位置为中心:

SELECT g.Student, g.Practical, g.Written, (g.Practical+g.Written) AS SumColumn 
FROM Grades g
LEFT JOIN Grades g2 on g2.Practical+g2.Written > g.Practical+g.Written
GROUP BY g.Student, g.Practical, g.Written, (g.Practical+g.Written) AS SumColumn 
HAVING COUNT(*) < 5
ORDER BY g.Practical+g.Written DESC

这可以通过加入所有得分较高的学生,然后使用 HAVING 子句过滤掉那些得分低于 5 且得分较高的学生 - 让您获得前 5 名。

需要左连接来返回得分最高的人,这些人没有其他得分更高的学生可以加入。

平局全部返回,在第 5 次平局的情况下导致超过 5 行。

通过不使用从 darabase 到数据库不同的行位置逻辑,这个查询也是完全可移植的。

请注意,ORDER BY 是可选的。

于 2014-07-06T22:48:06.673 回答
0

使用 Oracle 的 PLSQL,您可以:

SELECT score.Student, Practical, Written, (Practical+Written) as SumColumn  
FROM ( SELECT Student, DENSE_RANK() OVER (ORDER BY Score DESC) as Score_dr
       FROM VOTES ) as score, students
WHERE score.score_dr <= 5
and score.Student = students.Student
order by score.Score_dr;
于 2014-07-06T13:25:17.067 回答
0

您可以轻松地将第一个查询的投影包含在第二个查询的子查询中。

SELECT Student
       , Practical
       , Written
       , tot_score 
FROM (
    SELECT Student
           , Practical
           , Written
           , (Practical+Written) AS tot_score 
           , DENSE_RANK() OVER (ORDER BY (Practical+Written) DESC) as Score_dr
     FROM Grades
    )
WHERE Student_dr <= 5
order by Student_dr;

分析函数的一个优点是我们可以在任何查询中使用它们。这将它们与聚合函数区分开来,在聚合函数中,我们需要在 GROUP BY 子句中包含所有非聚合列(至少对于 Oracle)。

于 2014-07-07T07:14:13.773 回答