我有一张名为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;
答案 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)。