用于计算样本的最大值,最小值和模式的SQL查询

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)

ugh*_*hai 5

您可以使用这样的组合ROW_NUMBER和聚合函数OVER.

ROW_NUMBER() OVER(PARTITION BY Class ORDER BY ABS(Marks - AvgMarks)) 得到一个学生,其标记最接近班级的平均分.

SQL小提琴

询问

;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)