MySQL窗口函數(shù)實(shí)現(xiàn)榜單排名
相信大家在日常的開發(fā)中經(jīng)常會(huì)碰到榜單類的活動(dòng)需求,通常在榜單中都會(huì)要求返回排名,今天我們就用MySQL的窗口函數(shù)來快速實(shí)現(xiàn)一下
首先,先建一個(gè)測(cè)試表
create table praise_record(
id bigint primary key auto_increment,
name varchar(10),
praise_num int
) ENGINE=InnoDB;
然后讓chatGpt給我們生成幾條測(cè)試數(shù)據(jù)
INSERT INTO praise_record (name, praise_num) VALUES ('John', 5);
INSERT INTO praise_record (name, praise_num) VALUES ('Jane', 3);
INSERT INTO praise_record (name, praise_num) VALUES ('Bob', 10);
INSERT INTO praise_record (name, praise_num) VALUES ('Alice', 3);
INSERT INTO praise_record (name, praise_num) VALUES ('David', 7);
INSERT INTO praise_record (name, praise_num) VALUES ('oct', 7);
然后就可以開始實(shí)現(xiàn)我們的需求:返回點(diǎn)贊的榜單,并返回排名
rank()
使用rank()函數(shù)返回點(diǎn)贊的榜單, rank() over()
## 注意這里返回的rank字段要用反引號(hào)包起來 select name, praise_num, rank() over (order by praise_num desc) as `rank` from praise_record; +-------+------------+------+ | name | praise_num | rank | +-------+------------+------+ | Bob | 10 | 1 | | David | 7 | 2 | | oct | 7 | 2 | | John | 5 | 4 | | Jane | 3 | 5 | | Alice | 3 | 5 | +-------+------------+------+
可以看到使用rank()函數(shù)的時(shí)候相同的點(diǎn)贊數(shù)會(huì)返回相同的排名,排名會(huì)產(chǎn)生跳躍,最終的排名不是連續(xù)的
dense_rank()
使用dense_rank()函數(shù)返回點(diǎn)贊的榜單, dense_rank() over()
select name, praise_num, dense_rank() over (order by praise_num desc) as `rank` from praise_record; +-------+------------+------+ | name | praise_num | rank | +-------+------------+------+ | Bob | 10 | 1 | | David | 7 | 2 | | oct | 7 | 2 | | John | 5 | 3 | | Jane | 3 | 4 | | Alice | 3 | 4 | +-------+------------+------+
與rank()函數(shù)相同的是,相同點(diǎn)贊數(shù)會(huì)返回相同的排名,但是dense_rank()返回的最終排名是連續(xù)的排名
row_number()
row_number()函數(shù)返回點(diǎn)贊的榜單,row_number() over()
select name, praise_num, row_number() over (order by praise_num desc) as `rank` from praise_record; +-------+------------+------+ | name | praise_num | rank | +-------+------------+------+ | Bob | 10 | 1 | | David | 7 | 2 | | oct | 7 | 3 | | John | 5 | 4 | | Jane | 3 | 5 | | Alice | 3 | 6 | +-------+------------+------+
row_number()函數(shù)適合當(dāng)返回的列表只需要序號(hào)時(shí)使用
以上三個(gè)函數(shù)都是MySQL8.0新加入的,所以在MySQL5.7這些老版本上我們可以模擬實(shí)現(xiàn)一下,順便學(xué)習(xí)一下這三個(gè)窗口函數(shù)的實(shí)現(xiàn)原理
rank()函數(shù)的模擬實(shí)現(xiàn)
select p1.name, p1.praise_num, count(p2.praise_num) + 1 as `rank` from praise_record p1 left join praise_record p2 on p1.praise_num < p2.praise_num group by p1.name, p1.praise_num order by `rank`; +-------+------------+------+ | name | praise_num | rank | +-------+------------+------+ | Bob | 10 | 1 | | David | 7 | 2 | | oct | 7 | 2 | | John | 5 | 4 | | Jane | 3 | 5 | | Alice | 3 | 5 | +-------+------------+------+
我們可以使用自聯(lián)接的方式將每個(gè)分?jǐn)?shù)低于當(dāng)前行分?jǐn)?shù)的記錄計(jì)數(shù),最后將計(jì)數(shù)值加1作為當(dāng)前行的排名,來模擬實(shí)現(xiàn)rank()
dense_rank()的模擬實(shí)現(xiàn)
select p1.name, p1.praise_num, count(distinct p2.praise_num) + 1 as `dense_rank` from praise_record p1 left join praise_record p2 on p1.praise_num < p2.praise_num group by p1.name, p1.praise_num order by `dense_rank`; +-------+------------+------------+ | name | praise_num | dense_rank | +-------+------------+------------+ | Bob | 10 | 1 | | oct | 7 | 2 | | David | 7 | 2 | | John | 5 | 3 | | Jane | 3 | 4 | | Alice | 3 | 4 | +-------+------------+------------+
dense_rank的實(shí)現(xiàn)與rank差不多,唯一的區(qū)別是增加了distinct對(duì)點(diǎn)贊數(shù)做了去重,這樣子對(duì)不同的點(diǎn)贊數(shù)返回的排名就是連續(xù)的
row_number的模擬實(shí)現(xiàn)
##使用自定義變量得先初始化 set @rowNum = 0; select name, praise_num, @rowNum := @rowNum +1 as `row_number` from praise_record order by praise_num desc ; +-------+------------+------------+ | name | praise_num | row_number | +-------+------------+------------+ | Bob | 10 | 1 | | David | 7 | 2 | | oct | 7 | 3 | | John | 5 | 4 | | Jane | 3 | 5 | | Alice | 3 | 6 | +-------+------------+------------+
我們可以使用一個(gè)rowNum變量來記錄行號(hào),每一行的數(shù)據(jù)rowNUm都+1,這樣子就可以得到我們想要的序號(hào)
總結(jié)
1.rank()函數(shù)返回的排名會(huì)產(chǎn)生跳躍
2.dense_rank()函數(shù)返回的排名是連續(xù)的
3.row_number()函數(shù)返回的排名類似序號(hào)
4.窗口函數(shù)是MySQL8.0新增的特性,如果在低版本的MySQL要自己模擬實(shí)現(xiàn)一下
到此這篇關(guān)于MySQL窗口函數(shù)實(shí)現(xiàn)榜單排名的文章就介紹到這了,更多相關(guān)MySQL 榜單排名內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MYSQL設(shè)置觸發(fā)器權(quán)限問題的解決方法
這篇文章主要介紹了MYSQL設(shè)置觸發(fā)器權(quán)限問題的解決方法,需要的朋友可以參考下2014-09-09
MySQL 給用戶添加 ALTER VIEW 的權(quán)限的步驟
在 MySQL 中,用戶權(quán)限的管理是非常重要的,以確保數(shù)據(jù)庫安全性和數(shù)據(jù)完整性,這篇文章主要介紹了MySQL 給用戶添加 ALTER VIEW 的權(quán)限,需要的朋友可以參考下2024-05-05
MySQL報(bào)錯(cuò) table “xxx” doesn‘t exit的解決
本文主要介紹了MySQL報(bào)錯(cuò) table “xxx” doesn‘t exit的解決,主要原因是英文字母大小寫敏感導(dǎo)致,下面就來介紹一下解決方法,感興趣的可以了解一下2023-10-10
Mysql下自動(dòng)刪除指定時(shí)間以前的記錄的操作方法
這篇文章主要介紹了MySQL下自動(dòng)刪除指定時(shí)間以前的記錄的操作方法,需要的朋友可以參考下2018-08-08
MySQL?原理與優(yōu)化之Limit?查詢優(yōu)化
這篇文章主要介紹了MySQL?原理與優(yōu)化之Limit?查詢優(yōu)化,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08
MySQL授權(quán)用戶訪問數(shù)據(jù)操作方式
用戶授權(quán)操作可以控制數(shù)據(jù)庫用戶對(duì)數(shù)據(jù)庫對(duì)象的訪問權(quán)限,本文就來介紹MySQL授權(quán)用戶訪問數(shù)據(jù)操作方式,感興趣的可以了解一下2023-10-10
MYSQL中查詢LONGBLOB類型數(shù)據(jù)的大小的詳細(xì)示例
在MySQL中,LONGBLOB?是一種二進(jìn)制大對(duì)象(BLOB)數(shù)據(jù)類型,用于存儲(chǔ)大量的二進(jìn)制數(shù)據(jù),但是,LONGBLOB?數(shù)據(jù)類型本身并不直接存儲(chǔ)數(shù)據(jù)的大?。ㄩL度),它存儲(chǔ)的是二進(jìn)制數(shù)據(jù)的實(shí)際內(nèi)容,這篇文章主要介紹了MYSQL中怎么查詢LONGBLOB類型數(shù)據(jù)的大小,需要的朋友可以參考下2024-06-06

