[5]-MySQL排序總結

一、對查詢結果進行排序(ORDER BY)

1.ORDED BY 子句
使用SELECT抽取數據時,數據的顯示是無序的,想要得到有序的數據,那么我們就需要使用ORDER BY子句進行排序。
2.ORDED BY 子句語法:

SELECT <列1>,<列2>,<列3>,......
FROM <表名>
ORDER BY <排序基準1>,<排序基準2>,.....
ORDED BY 子句(商品的銷售單價升序排列)
其中desc表示降序,asc表示升序排列。

二、rank,dense_rank,row_number 使用上的區別

RANK:跳躍排序
DENSE_RANK:連續排序
row_number:沒有重復值的排序[記錄相等也是不重復的]可以進行分頁使用。

MySQL中不存在類似于SQL Server或Orcal中的以上三個函數來得到排名。

而在實際的工作中,常常需要將查詢后排序得到的排名給記錄下來。由于項目需要,不僅要對成績進行排名,而且需要相同成績的具有相同的排名。這里先來介紹用變量賦值的方法來實現排序。這里取經典面試題里的排序問題來講解。請看下面三種排序類型

1.按各科成績進行排序,并顯示排名, Score 重復時保留名次空缺
2.按各科成績進行排序,并顯示排名, Score 重復時合并名次

我們來看看怎么解答:


分數表
1)按各科成績進行排序,并顯示排名, Score 重復時保留名次空缺.

對于15題排序就是沒有重復值得排序(1-2-3-4)

select sc.CId ,@curRank:=@curRank+1 as rank,
sc.score from (select @curRank:=0) as t ,sc
ORDER BY sc.score desc;

第一:要在mysql中聲明一個變量,你必須在變量名之前使用@符號。FROM子句中的(@curRank := 0)部分允許我們進行變量初始化,而不需要單獨的SET命令。當然,也可以使用SET,但它會處理兩個查詢

set @curRank:=0;
select sc.CId ,@curRank:=@curRank+1 as rank,sc.score
from sc ORDER BY sc.score desc;

第二:一定要進行排序order by ,否則會出現這樣的情況:

那如果我們用函數rank_number()函數怎么實現
select *,
row_number()  over(partition by Cid order by score desc) as 'rank' from sc;

其中里面的partition by +某個字段表示以什么字段來排序。

2).按各科成績進行排序,并顯示排名, Score 重復時合并名次
對于這題就是連續排序(1-2-2-2-3)
select sc.CId , 
case when @fontscore=score then @curRank 
when @fontscore:=score then @curRank:=@curRank+1  
end as rank,sc.score
from (select @curRank:=0 ,@fontage:=null) as t ,sc
ORDER BY sc.score desc

現在,如果我們希望為并列數據的行賦予相同的排名,則意味著那些在排名比較列中具有相同值的行應在MySQL中計算排名時保持相同的排名(例如在我們的例子中的score)。為此,我們使用了一個額外的變量@fontscore。

那我們來看用dense_rank()連續排序怎么實現:
select *,
dense_rank() over(partition by Cid order by score desc) as 'rank' from sc;

以上函數的語法規則都是一樣的
select * from 函數() over(partition by 字段1 order by 字段2 desc or asc) as rank from table;

3).在MySQL中實現Rank普通并列排名函數(1-2-2-2-5),這里舉另外一個例子

當使用RANK()函數時,如果兩個或以上的行排名并列,則相同的行都會有相同的排名,但是實際排名中存在有關系的差距。

select pid, name, age, rank from
(select  pid, name, age,
@curRank := IF(@prevRank = age, @curRank, @incRank) AS rank, 
@incRank := @incRank + 1, 
@prevRank := age
from players p, (
select @curRank :=0, @prevRank := NULL, @incRank := 1
) r 
ORDER BY age) s

在這里我們可以看到,Andre,Vino,John和Tom都有相同的age,所以他們排名并列第二。下一個最高年齡的球員(Brian)排名第6,而不是第3,因為有4個人并列排名在第2。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。