1. 程式人生 > >SQL的老題目:查詢學生平均成績及其名次

SQL的老題目:查詢學生平均成績及其名次

SQL的老題目了。

Student(S#,Sname,Sage,Ssex) 學生表
Course(C#,Cname,T#) 課程表
SC(S#,C#,score) 成績表
Teacher(T#,Tname) 教師表

24、查詢學生平均成績及其名次

答:SELECT 1+(SELECT COUNT( distinct 平均成績)
              FROM (SELECT S#,AVG(score) AS 平均成績
                      FROM SC
                  GROUP BY S#
                  ) AS T1
            WHERE 平均成績 > T2.平均成績) as 名次,
      S# as 學生學號,平均成績
    FROM (SELECT S#,AVG(score) 平均成績
            FROM SC
        GROUP BY S#
        ) AS T2
    ORDER BY 平均成績 desc;

網上找了一下,沒有分析的文章,或許太簡單了。那我們自己來分析。這裡涉及到一個SELECT 表1.* FROM 表1 where 表1.欄位=表2.欄位的表遍歷匹配的問題表1、表2是資料庫中同一個表或同一個表查詢結果的別名)。

但是程式碼一大堆,看得一頭霧水,我們先拆開來,看T1表的查詢(先去了COUNT有助於我們的分析)。

 圖 T1

接著看,T2表的查詢。(加入"order by 平均成績",可以讓之後的對比效果更明顯)

 圖 T2

對比T1和T2的SQL查詢語句及結果,可以看出,除了distinct的效果以外,其他程式碼基本上一致。

拆分開來看,是簡單的SQL語句,那麼聯合起來是一種什麼效果呢?語句執行的順序又是什麼呢?

我們參照圖T1圖T2一步步來描述語句的執行順序。

清晰理解了這一點,相信整段SQL程式碼就不難理解了。完整查詢結果如下:

另外需要補充一點的是distinct在這裡的使用效果。

需不需要distinct,要看排名的要求方式,要distinct是指順序排名(如上面的例子,則為1,2,2,3...),不要是指跳序排名(如上面的例子,則為1,2,2,4...)。可見後者其實就是我們日常成績的排名方式。