堂弟的同學找我,他要寫一個學生成績管理系統,其中一個模塊需要提供用戶查詢學生成績名次排名,名次排名里需要考慮到成績相同的情況。這個讓我想起N年前我讀書時候做這個問題,當時我用了最笨的方法,使用程序來排名,而沒有使用SQL語句,自然效率相當低下。
需求簡述:
例如我有這樣一個成績表 編號 姓名 成績
1 張三 90
2 李四 85
3 王五 100
4 趙六 85
5 汪一 100
6 周九 78
7 何二 56
然后我希望排名次,因為這里有同分,所以必然會出現並列名次。網絡上關於並列成績名次排名有兩種方式,其一是這樣:
A
名次 姓名 成績
1 王五 100
1 汪一 100
3 張三 90
4 趙六 85
4 李四 85
6 周九 78
7 何二 56
第二種還是這樣:
B
名次 姓名 成績
1 王五 100
1 汪一 100
2 張三 90
3 趙六 85
3 李四 85
4 周九 78
5 何二 56
SQL語句是一種很實用的技巧,希望和朋友們多交流,現在拋磚引玉把自己的3句SQL語句貼出來共享,拋磚引玉,希望大家多多指教,拍磚的輕點。
對於A方式,比較好辦,以Access數據庫為例(其他數據庫語法大同小異,變化一下對應的即可),可以寫成這樣:
SELECT e.place AS 名次, d.name AS 姓名, d.mark AS 成績
FROM [select a.id,count(b.id)+1 as place from sc a left join sc b on a.mark < b.mark group by a.id]. AS e INNER JOIN sc AS d ON e.id = d.id;
同時A方式也可以寫成這樣,效果等同,不過估計比上面那句效率低點:
SELECT e.place AS 名次, d.name AS 姓名, d.mark AS 成績
FROM [select a.id,count(iif(b.id is null,null,b.id))+1 as place from sc a left join sc b on a.mark<b.mark group by a.id]. AS e INNER JOIN sc AS d ON e.id = d.id;
而B方式則比較棘手,寫了半個鍾頭才寫好.......:
SELECT e.place AS 名次, d.name AS 姓名, d.mark AS 成績
FROM [select c.id,count(iif(c.mark is null,null,c.mark))+1 as place from (select a.id,b.mark from sc a left join sc b on a.mark < b.mark group by a.id,b.mark)c group by c.id]. AS e INNER JOIN sc AS d ON e.id = d.id;
轉載處:http://www.i-sx.net/bbs/viewthread.php?tid=157887