函式實現 MySQL排名函式實現

2021-10-14 21:08:04 字數 3355 閱讀 1921

現在有個需求對所有學生分數進行排名,並且列出名次。剛看到這個需求,我有點懵逼,完全沒有思路?,為什麼難一點需求,我就不會做呢? 去網上查詢資料,把所有實現都列出來,全部都要學會。

建立乙個分數表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

趙六961王五

962大衛913小明

904小龍885梁晨

876小五807張三

808趙武809李四

7010

威廉69

11小綠

6912

小紅60

13 併排名次展示

現在還有乙個問題,出現分數相同,並列排名,名次應該相同。我們使用乙個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

趙六961王五

961大衛912小明

903小龍884梁晨

875小五806張三

806趙武806李四

707威廉698小綠

698小紅60

9 併排名次跳過

如果出現並列排名,下乙個名次將自動跳過,比如出現兩個並列第一,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

趙六961王五

961大衛913小明

904小龍885梁晨

876小五807張三

807趙武807李四

7010

威廉69

11小綠

6911

小紅60

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

select 排序函式/聚合函式 over (  分割槽字段   order by  排序字段)
注意over 後面有乙個空格的,這個語法有點蛋疼,我自己試了十幾次才書寫成功。

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

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

排序函式主要有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

趙六9611

1王五961

21大衛9133

2小明904

43小龍8855

4梁晨876

65趙武8077

6小五807

86張三8079

6李四7010107

小綠69

11118威廉

6911128

小紅60

1313

9推薦閱讀:

好文章,我「在看」

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

資料庫準備 建立乙個分數表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,prima...

MySQL實現Rank高階排名函式

mysql中沒有rank排名函式,當我們需要查詢排名時,只能使用mysql資料庫中的基本查詢語句來查詢普通排名。儘管如此,可不要小瞧基礎而簡單的查詢語句,我們可以利用其來達到rank函式一樣的高階排名效果。在這裡我用乙個簡單例子來實現排名的查詢 首先我們先建立乙個我們需要進行高階排名查詢的playe...

MySQL中實現Rank排名高階函式

先舉例乙個 select name,time,currank currank 1 as rank from 表名,select currank 0 qorder by time1.要在mysql中宣告乙個變數,你必須在變數名之前使用 符號。from子句中的 currank 0 部分允許我們進行變數初...