1.需求描述: 查詢 班級總成績 前三名,總成績有相等的情況,所以會出現同時獲得名次。
2.運行環境: Winows 7 旗艦版,SQLServer 2008 R2
3.解決方案: 分別用 Union,Select+Case, Declare變量,三種方法查詢
4.具體編碼:
drop table Record go create table Record ( Student_No int identity(1,1) primary key, Student_Name varchar(20), Chinese float, Math float, English float, totalScore as Chinese+Math+English ) go insert into Record(Student_Name,Chinese,Math,English) values('劉德華',100,80,80) insert into Record(Student_Name,Chinese,Math,English) values('郭富城',100,100,60) insert into Record(Student_Name,Chinese,Math,English) values('施瓦辛格',100,70,70) insert into Record(Student_Name,Chinese,Math,English) values('劉志玲',100,90,50) insert into Record(Student_Name,Chinese,Math,English) values('終結者',100,90,50) insert into Record(Student_Name,Chinese,Math,English) values('蘭博',88,54,39) insert into Record(Student_Name,Chinese,Math,English) values('史泰龍',98,89,14) insert into Record(Student_Name,Chinese,Math,English) values('朱莉婭',10,42,10) insert into Record(Student_Name,Chinese,Math,English) values('羅素',10,76,66) insert into Record(Student_Name,Chinese,Math,English) values('畢達哥拉斯',18,98,78) insert into Record(Student_Name,Chinese,Math,English) values('萊布尼茨',87,98,45) insert into Record(Student_Name,Chinese,Math,English) values('牛頓',85,85,45) insert into Record(Student_Name,Chinese,Math,English) values('柏拉圖',12,78,89) go -----------------------第一種方法--------------------------------- select '第一名',* from Record where totalScore in ( select top 1 a.totalScore from ( select distinct totalScore from Record )a order by a.totalScore desc ) union select '第二名',* from Record where totalScore in ( select MIN(t.totalScore) from ( select top 2 a.totalScore from ( select distinct totalScore from Record )a order by a.totalScore desc ) t ) union select '第三名',* from Record where totalScore in ( select MIN(t.totalScore) from ( select top 3 a.totalScore from ( select distinct totalScore from Record )a order by a.totalScore desc )t )
-------------------第二種方法--------------------------
select * from( select Student_No,Student_Name,Chinese,Math,English,totalScore, case when totalScore=(select top 1 totalScore from (select distinct totalScore from Record) t order by totalScore desc) then '第一名' when totalScore=(select min(totalScore) from (select top 2 totalScore from (select distinct totalScore from Record) t order by totalScore desc)t2) then '第二名' when totalScore=(select min(totalScore) from (select top 3 totalScore from (select distinct totalScore from Record) t order by totalScore desc)t3) then '第三名' else null end as '排名' from Record )R where R.排名 is not null order by totalScore desc
-------------------第三種方法----------------- declare @max float set @max=(select top 1 totalScore from (select distinct totalScore from Record) t order by totalScore desc) declare @min float set @min=(select min(totalScore) from (select top 3 totalScore from (select distinct totalScore from Record) t order by totalScore desc)t2) select Student_No,Student_Name,Chinese,Math,English,totalScore, case when totalScore=@max then '第一名' when totalScore<@max and totalScore>@min then '第二名' when totalScore=@min then '第三名' else '無名' end as '排名' from Record order by totalScore desc -----------------case第二種用法--------------------------- declare @mid float set @mid=(select min(totalScore) from (select top 2 totalScore from (select distinct totalScore from Record) t order by totalScore desc)t2) select Student_No,Student_Name,Chinese,Math,English,totalScore, case totalScore when @max then '第一名' when @mid then '第二名' when @min then '第三名' else '無名' end as '排名' from Record order by totalScore desc
查詢結果:
拋磚引玉,能用其他算法 算出第四名,第五名,第六名。。。。。一直到100名
有四位高手提供了其他解決方案
高手 1:土豆烤肉
SELECT a.*,b.RankOrder,'第' + CONVERT(NVARCHAR(4),b.RankOrder) + '名' FROM Record a left JOIN ( SELECT ROW_NUMBER() OVER(ORDER BY TotalScore DESC) AS RankOrder,TotalScore FROM ( SELECT DISTINCT TotalScore FROM Record ) temp ) b ON A.totalScore = b.totalScore ORDER BY totalScore DESC
高手 2:小曉文盲
select *,'第' +convert(varchar,dense_rank() over( order by totalScore desc))+ '名' from Record order by totalScore desc
兩高手方法做了一個執行計划,下面是效果
高手3:靈X風
Create table #temp1(id int identity(1,1),Score int) INSERT INTO #temp1(Score) SELECT DISTINCT totalScore FROM Record ORDER BY totalScore DESC SELECT Record.*,'第'+convert(varchar,id)+'名' FROM Record LEFT JOIN #temp1 ON totalScore = Score ORDER BY id DROP TABLE #temp1
高手 4: JeffWong
WITH ScoreInfo AS ( SELECT [Student_No], [Student_Name],[Chinese],[Math],[English],[totalScore] ,DENSE_RANK() OVER(ORDER BY totalScore DESC) AS 'R' FROM [Record] ) SELECT [Student_No], [Student_Name],[Chinese],[Math],[English],[totalScore] ,'第'+ CONVERT(varchar,R)+'名' FROM ScoreInfo