mysql 排名函式 MySQL排名函式實現

2021-10-20 22:27:01 字數 2645 閱讀 6376

資料庫準備

建立乙個分數表s_score

create table `s_score` (`id` int not null auto_increment,`score` int not null default 0,`name` varchar(20) character set utf8mb4 null,primary key (`id`));

插入資料

insert into `s_score` (`name`, `score`) values('張三', 80),('小明', 90),('小紅', 60),('李四', 70),('趙武', 80),('梁晨', 87),('小綠', 69),('威廉', 69),('大衛', 91),('王五', 96),('趙六', 96),('小五', 80),('小龍', 88);

普通實現

在mysql8.0推出rank排名函式rank,完全支援這種需求,但是必須mysql8.0 以上版本才支援這個特性。8.0以下的版本有什麼方法實現呢,使用使用者變數,記錄名次。

使用者變數:以"@"開始,形式為"@var_name",以區分使用者變數及列名。它可以是任何隨機的,復合的標量表示式,只要其中沒有列指定。下面寫乙個小例子,展示如何使用使用者變數

select @a:=1 a,@b:=@a+1 b

執行結果

:= 是賦值的意思,與程式語言賦值有點區別。下面開始展示使用簡單sql實現rank排名函式效果

使用者變數簡單實現名次顯示

select name,score, @rank:=@rank+1 `rank` from s_score s,(select @rank:=0) q order by score desc

name

score

rank

趙六王五

大衛小明

小龍梁晨

小五張三

趙武李四

威廉小綠

小紅併排名次展示

現在還有乙個問題,出現分數相同,並列排名,名次應該相同。我們使用乙個temp變數來記錄前乙個分數值,判斷前面分數是否與當前相等,相等直接返回上乙個排名情況,否則排名+1。

select name,score,case when @temp_score=score then @rank when @temp_score:=score then @rank:=@rank+1 end`rank` from s_score s,(select @rank:=0,@temp_score:=null) q order by score desc

name

score

rank

趙六王五

大衛小明

小龍梁晨

小五張三

趙武李四

威廉小綠

小紅併排名次跳過

如果出現並列排名,下乙個名次將自動跳過,比如出現兩個並列第一,91應該變成第三名了,名次和人數相對應。

select name,score,rank from (select name ,score,@rank :=if( @temp_score = score, @rank, @rank_incr ) `rank`,@rank_incr := @rank_incr + 1,@temp_score := score from score s,(select@rank := 0,@temp_rank := null,@rank_incr := 1 ) q order by score desc) a

name

score

rank

趙六王五

大衛小明

小龍梁晨

小五張三

趙武李四

威廉小綠

小紅使用sql視窗函式

視窗函式的基本語法如下:

select 排序函式/聚合函式 over (  分割槽字段   order by  排序字段)

注意over 後面有乙個空格的,這個語法有點蛋疼,我自己試了十幾次才書寫成功。

根據維基百科解釋:視窗函式允許在當前記錄之前和之後訪問記錄中的資料。視窗函式定義一幀或一列視窗,其中當前行周圍具有給定的長度,並跨視窗中的資料集執行計算。可以這樣理解,視窗就是資料集合,函式就是計算資料方法。

partiton by是可選的。如果不使用partition by,那麼就是將整張表作為乙個集合,最後使用排序函式得到的就是每一條記錄根據排序列的排序編號。

排序函式主要有rank()、dense_rank、row_number,他們主要區別:

rank():   對同乙個字段排序,出現相同時,會並列排名,並且會出現排名間隙。

dense_rank() :  對同乙個字段排序,出現相同時,會出現並列排名,排名連續的

row_number():  對同乙個字段排序,排名是聯絡的,即使出現相同,不會並列排名次

select name,score, rank() over (order by score desc) `rank`,row_number() over (order by score desc) `row`,dense_rank()over (order by score desc) `dense` from s_score

name

score

rank

rowdense

趙六王五

大衛小明

小龍梁晨

趙武小五

張三李四

小綠威廉

小紅參考文件

mysql儲存函式查詢排名 MySQL排名函式

應用場景 編寫乙個 sql 查詢來實現分數排名。如果兩個分數相同,則兩個分數排名 rank 相同。請注意,平分後的下乙個名次應該是下乙個連續的整數值。換句話說,名次之間不應該有 間隔 id score 1 3.50 2 3.65 3 4.00 4 3.85 5 4.00 6 3.65 例如,根據上述...

mysql 更新 排名 更新MySQL表中的排名

一種選擇是使用排名變數,例如 update player join select p.playerid,currank currank 1 as rank from player p join select currank 0 r order by p.points desc ranks on ra...

mysql分組排名 mysql分組排名

1.建立表並寫入測試資料 create table tb rank score city varchar 20 score int insert into tb rank score values sz 89 insert into tb rank score values sz 76 insert...