現在有個需求對所有學生分數進行排名,並且列出名次。剛看到這個需求,我有點懵逼,完全沒有思路?,為什麼難一點需求,我就不會做呢? 去網上查詢資料,把所有實現都列出來,全部都要學會。
建立乙個分數表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 部分允許我們進行變數初...