use*_*024 2 sql sql-server sql-server-2008-r2
我有一张学生分数表如下:
SrNo Class Name Marks
1 1A Student1 67
2 1A Student2 62
3 1A Student3 65
4 1A Student4 78
5 1A Student5 28
6 1B Student6 57
7 1B Student7 65
8 1B Student8 85
9 1B Student9 18
10 1B Student10 8
Run Code Online (Sandbox Code Playgroud)
我希望结果为每个类的3行,包括最高,最低和平均标记.
结果理想情况是:
SrNo Class Student Marks
4 1A Student4 78
5 1A Student5 28
2 1A Student2 62
8 1B Student8 85
10 1B Student10 8
6 1B Student6 57
Run Code Online (Sandbox Code Playgroud)
您可以使用这样的组合ROW_NUMBER和聚合函数OVER.
ROW_NUMBER() OVER(PARTITION BY Class ORDER BY ABS(Marks - AvgMarks)) 得到一个学生,其标记最接近班级的平均分.
询问
;WITH CTE AS
(
SELECT
MAX(Marks)OVER(PARTITION BY Class) MaxMarks,
MIN(Marks)OVER(PARTITION BY Class) MinMarks,
AVG(Marks)OVER(PARTITION BY Class) AvgMarks,
[SrNo], [Class], [Name], [Marks]
FROM Class
), CTEAvg as
(
SELECT [SrNo], [Class], [Name], [Marks],MaxMarks,MinMarks,
ROW_NUMBER() OVER(PARTITION BY Class ORDER BY ABS(Marks - AvgMarks)) ClosestAvg
FROM CTE
)
SELECT [SrNo], [Class], [Name], [Marks]
FROM CTEAvg
WHERE [Marks] = MaxMarks
OR [Marks] = MinMarks
OR ClosestAvg = 1;
Run Code Online (Sandbox Code Playgroud)
产量
| SrNo | Class | Name | Marks |
|------|-------|-----------|-------|
| 2 | 1A | Student2 | 62 |
| 4 | 1A | Student4 | 78 |
| 5 | 1A | Student5 | 28 |
| 6 | 1B | Student6 | 57 |
| 10 | 1B | Student10 | 8 |
| 8 | 1B | Student8 | 85 |
Run Code Online (Sandbox Code Playgroud)