在MySQL中實現Rank高階排名函式

2021-09-07 20:11:12 字數 4259 閱讀 5804

mysql中沒有rank排名函式,當我們需要查詢排名時,只能使用mysql資料庫中的基本查詢語句來查詢普通排名。儘管如此,可不要小瞧基礎而簡單的查詢語句,我們可以利用其來達到rank函式一樣的高階排名效果。

在這裡我用乙個簡單例子來實現排名的查詢:

首先我們先建立乙個我們需要進行高階排名查詢的players表,

create table `players` (

`pid` int(2) not null auto_increment,

`name` varchar(50) not null, `age` int(2) not null, primary key (`pid`), unique key `name` (`name`) ) engine=innodb default charset=latin1; insert into `players` (`pid`, `name`, `age`) values (1, 'samual', 25), (2, 'vino', 20), (3, 'john', 20), (4, 'andy', 22), (5, 'brian', 21), (6, 'dew', 24), (7, 'kris', 25), (8, 'william', 26), (9, 'george', 23), (10, 'peter', 19), (11, 'tom', 20), (12, 'andre', 20);

在這裡,我們希望獲得乙個排名字段的列,以及age的公升序排列。所以我們的查詢語句將是:

select pid, name, age, @currank := @currank + 1 as rank

from players p, (

select @currank := 0 ) q order by age

| pid |    name | age | rank |

|-----|---------|-----|------| | 10 | peter | 19 | 1 | | 12 | andre | 20 | 2 | | 2 | vino | 20 | 3 | | 3 | john | 20 | 4 | | 11 | tom | 20 | 5 | | 5 | brian | 21 | 6 | | 4 | andy | 22 | 7 | | 9 | george | 23 | 8 | | 6 | dew | 24 | 9 | | 7 | kris | 25 | 10 | | 1 | samual | 25 | 11 | | 8 | william | 26 | 12 |

要在mysql中宣告乙個變數,你必須在變數名之前使用@符號。from子句中的(@currank := 0)部分允許我們進行變數初始化,而不需要單獨的set命令。當然,也可以使用set,但它會處理兩個查詢:

set @currank := 0;

select pid, name, age, @currank := @currank + 1 as rank from players order by age

首要按age的降序排列,其次按name進行排列,只需修改查詢語句加上order bydesc以及列名即可。

select pid, name, age, @currank := @currank + 1 as rank

from players p, (

select @currank := 0 ) q order by age desc, name

| pid |    name | age | rank |

|-----|---------|-----|------| | 8 | william | 26 | 1 | | 7 | kris | 25 | 2 | | 1 | samual | 25 | 3 | | 6 | dew | 24 | 4 | | 9 | george | 23 | 5 | | 4 | andy | 22 | 6 | | 5 | brian | 21 | 7 | | 12 | andre | 20 | 8 | | 3 | john | 20 | 9 | | 11 | tom | 20 | 10 | | 2 | vino | 20 | 11 | | 10 | peter | 19 | 12 |

現在,如果我們希望為並列資料的行賦予相同的排名,則意味著那些在排名比較列中具有相同值的行應在mysql中計算排名時保持相同的排名(例如在我們的例子中的age)。為此,我們使用了乙個額外的變數。

select pid, name, age, 

case

when @prevrank = age then @currank

when @prevrank := age then @currank := @currank + 1

end as rank from players p, (select @currank :=0, @prevrank := null) r order by age

| pid |    name | age | rank |

|-----|---------|-----|------| | 10 | peter | 19 | 1 | | 12 | andre | 20 | 2 | | 2 | vino | 20 | 2 | | 3 | john | 20 | 2 | | 11 | tom | 20 | 2 | | 5 | brian | 21 | 3 | | 4 | andy | 22 | 4 | | 9 | george | 23 | 5 | | 6 | dew | 24 | 6 | | 7 | kris | 25 | 7 | | 1 | samual | 25 | 7 | | 8 | william | 26 | 8 |

如上所示,具有相同資料和排行的兩行或多行,它們都會獲得相同的排名。玩家andre, vino, john 和tom都有相同的age,所以他們排名並列第二。下乙個最高age的玩家(brian)排名第3。這個查詢相當於mssql和oracle 中的dense_rank()函式。

當使用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

這是乙個查詢中的子查詢。我們使用三個變數(@incrank,@prevrank,@currank)來計算關係的情況下,在查詢結果中我們已經補全了因為並列而導致的排名空位。我們已經封閉子查詢到查詢。這個查詢相當於mssql和oracle中的rank()函式。

| pid |    name | age | rank |

|-----|---------|-----|------| | 10 | peter | 19 | 1 | | 12 | andre | 20 | 2 | | 2 | vino | 20 | 2 | | 3 | john | 20 | 2 | | 11 | tom | 20 | 2 | | 5 | brian | 21 | 6 | | 4 | andy | 22 | 7 | | 9 | george | 23 | 8 | | 6 | dew | 24 | 9 | | 7 | kris | 25 | 10 | | 1 | samual | 25 | 10 | | 8 | william | 26 | 12 |

在這裡我們可以看到,andre,vino,john和tom都有相同的age,所以他們排名並列第二。下乙個最高年齡的球員(brian)排名第6,而不是第3,因為有4個人並列排名在第2。

好的,我希望在這些例子後,能讓你了解rank()和dense_rank()之間的區別,並且知道在**應使用哪個查詢來獲取mysql中的rank函式。謝謝。

在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 部分允許我們進行變數初...

MySQL實現Rank高階排名函式

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