2015-07-03 50 views
2

我有一個表爲學生的標記如下:SQL查詢用於計算樣本的最大值,最小值和模式

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 

我想從具有最高,最低及平均分數每一等級的結果爲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 
+4

什麼是你的DBMS?我們可以選擇嗎? –

+0

@Sebastien sql 2008 r2 – user3625024

+1

我認爲平均分不應該與任何記錄相關,因爲您已經在結果中指定了srno。 –

回答

0

你可以嘗試這樣的事情來實現它:

-- Create demo data 
CREATE TABLE #temp(SrNo int, Class nvarchar(5), Name nvarchar(50), Marks int) 

INSERT INTO #temp(SrNo, Class, Name, Marks) 
VALUES (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) 

-- your part 
SELECT t.* 
FROM (
    SELECT Class, 
      MIN(Marks) as min_marks, 
      AVG(Marks) as avg_marks, 
      MAX(Marks) as max_marks 
    FROM #temp 
    GROUP BY class 
) as data 
OUTER APPLY (
    SELECT TOP 1 t.marks as nearest_avg 
    FROM #temp as t 
    WHERE t.class = data.Class 
    ORDER BY CASE WHEN data.avg_marks-marks >= 0 THEN data.avg_marks-Marks ELSE Marks-data.avg_marks END 
) as avg_data 
INNER JOIN #temp as t 
     ON t.Class = data.Class 
     AND( 
      t.Marks = data.min_marks 
      OR t.marks = avg_data.nearest_avg 
      OR t.marks = data.max_marks 
     ) 

-- Cleanup 
DROP TABLE #temp 
+0

工程就像一個魅力。謝謝Ionic – user3625024

+0

很高興幫助你。 – Ionic

5

您可以使用ROW_NUMBER組合和聚合函數與OVER這樣。

ROW_NUMBER() OVER(PARTITION BY Class ORDER BY ABS(Marks - AvgMarks))得到的學生的分數最接近班級的平均水平。

SQL Fiddle

查詢

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

輸出

| 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 | 
0

這是最高/最低馬克類明智的,

Select Class, Student, Marks from 
(
    Select row_number() over (order by class, marks desc) as row_id, 
     class, 
     student, 
     marks 
    from student 
)T 
where row_id = 1 or row_id = 
(
    select max(row_id) from t 
) 
相關問題