试图找出如何加入这些查询

时间:2014-07-06 13:21:38

标签: sql oracle top-n

我有一张名为grade的表。一个名为Students,Practical,Written的专栏。我试图通过测试的总分来找出前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;

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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是可选的。

答案 2 :(得分: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)。