这是我在申请中必须处理的最后一个问题,我希望有人会帮助,因为我很无能,我做了我的研究,找不到合适的解决方案。
我有一个'大学管理'申请。我需要制作包含少量表格的报告。
问题出在SQL Query中我必须完成。查询需要列出最佳学生名单,学生“最佳”的条件是等级平均。
我有3列(students.stID& examines.grades)。我需要得到我的'examines.grades'列的平均值,将表格从最高(平均成绩)排序到最低,我需要过滤'n'最佳'平均值'。
用户可以输入过滤器编号,正如我所说,应用程序需要显示“n”个最佳平均值。
问题在于我的SQL知识(不是mySQL文学而是T-SQL)。这就是我对我的SQL查询的看法,但问题在于“SELECT TOP”,因为当我按下我的按钮时,应用程序仅从所选的TOP'n'行取平均值。
SELECT TOP(@topParam) student.ID, AVG(examines.grades)
FROM examines INNER JOIN
student ON examines.stID = student.stID
WHERE (examines.grades > 1)
例如:
StudentID Grade
1 2
2 5
1 5
2 2
2 4
2 2
EXIT:
StudentID Grade_Average
1 3.5
2 3.25
答案 0 :(得分:1)
对于每个{{1>,您应该使用group by
子句来计算平均成绩(如果examines.grades
具有整数类型,则应cast
为浮点类型) }和student.ID
子句将输出限制为仅order by
n 最高平均成绩:
top
答案 1 :(得分:1)
不耐烦,我认为这就是你要找的东西。您没有指定您正在使用的SQL Server版本。
DECLARE @topParam INT = 3; -- Default
DECLARE @student TABLE (StudentID INT); -- Just for testing purpose
DECLARE @examines TABLE (StudentID INT, Grades INT);
INSERT INTO @student (StudentID) VALUES (1), (2);
INSERT INTO @examines (StudentID, Grades)
VALUES (1, 2), (2, 5), (1, 5), (2, 2), (2, 4), (2, 2);
SELECT DISTINCT TOP(@topParam) s.StudentID, AVG(CAST(e.grades AS FLOAT)) OVER (PARTITION BY s.StudentID) AS AvgGrade
FROM @examines AS e
INNER JOIN @student AS s
ON e.StudentID = s.StudentID
WHERE e.grades > 1
ORDER BY AvgGrade DESC;
如果您提供一些基本数据,我会根据您的需求调整查询。
结果:
StudentID AvgGrade
--------------------
1 3.500000
2 3.250000
快速解释:
查询在派生表中查找平均成绩,然后查询它按其排序。另一个提示:如果有多名学生可以申请第三名,你可以在WITH TIES
条款中使用TOP
选项来吸引更多学生。
如果您想按照我在评论中的建议制作程序,请使用以下代码段:
CREATE PROCEDURE dbo.GetTopStudents
(
@topParam INT = 3
)
AS
BEGIN
BEGIN TRY
SELECT DISTINCT TOP(@topParam) s.StudentID, AVG(CAST(e.grades AS FLOAT)) OVER (PARTITION BY s.StudentID) AS AvgGrade
FROM examines AS e
INNER JOIN student AS s
ON e.StudentID = s.StudentID
WHERE e.grades > 1
ORDER BY AvgGrade DESC;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER(), ERROR_MESSAGE();
END CATCH
END
后来就这样称呼它。这是封装逻辑的好方法。
EXEC dbo.GetTopStudents @topParam = 3;
答案 2 :(得分:0)
不需要返回重复行的A Windowed Aggregate,然后您需要DISTINCT再次删除它们。这是一个简单的聚合,你的原始查询已经非常接近了:
SELECT TOP(@topParam) student.ID, AVG(CAST(grade AS FLOAT)) as AvgGrade
FROM examines INNER JOIN
student ON examines.stID = student.stID
WHERE (examines.grades > 1)
group by student.ID
order by AvgGrade DESC