總結(jié)幾種MySQL中常見(jiàn)的排名問(wèn)題
前言:
在某些應(yīng)用場(chǎng)景中,我們經(jīng)常會(huì)遇到一些排名的問(wèn)題,比如按成績(jī)或年齡排名。排名也有多種排名方式,如直接排名、分組排名,排名有間隔或排名無(wú)間隔等等,這篇文章將總結(jié)幾種MySQL中常見(jiàn)的排名問(wèn)題。
創(chuàng)建測(cè)試表
create table scores_tb ( id int auto_increment primary key, xuehao int not null, score int not null) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into scores_tb (xuehao,score) values (1001,89),(1002,99),(1003,96),(1004,96),(1005,92),(1006,90),(1007,90),(1008,94);# 查看下插入的數(shù)據(jù)mysql> select * from scores_tb;+----+--------+-------+| id | xuehao | score |+----+--------+-------+| 1 | 1001 | 89 || 2 | 1002 | 99 || 3 | 1003 | 96 || 4 | 1004 | 96 || 5 | 1005 | 92 || 6 | 1006 | 90 || 7 | 1007 | 90 || 8 | 1008 | 94 |+----+--------+-------+
1.普通排名
按分?jǐn)?shù)高低直接排名,從1開(kāi)始,往下排,類似于row number。下面我們給出查詢語(yǔ)句及排名結(jié)果。
# 查詢語(yǔ)句SELECT xuehao, score, @curRank := @curRank + 1 AS rankFROM scores_tb, (SELECT @curRank := 0) rORDER BY score desc;# 排序結(jié)果+--------+-------+------+| xuehao | score | rank |+--------+-------+------+| 1002 | 99 | 1 || 1003 | 96 | 2 || 1004 | 96 | 3 || 1008 | 94 | 4 || 1005 | 92 | 5 || 1006 | 90 | 6 || 1007 | 90 | 7 || 1001 | 89 | 8 |+--------+-------+------+
上述查詢語(yǔ)句中,我們申明了一個(gè)變量 @curRank ,并將此變量初始化為0,查得一行將此變量加一,并以此作為排名。我們看到這類排名是沒(méi)間隔的并且有些分?jǐn)?shù)相同但排名不同。
2.分?jǐn)?shù)相同,名次相同,排名無(wú)間隔
# 查詢語(yǔ)句SELECT xuehao, score, CASEWHEN @prevRank = score THEN @curRankWHEN @prevRank := score THEN @curRank := @curRank + 1END AS rankFROM scores_tb, (SELECT @curRank :=0, @prevRank := NULL) rORDER BY score desc;# 排名結(jié)果+--------+-------+------+| xuehao | score | rank |+--------+-------+------+| 1002 | 99 | 1 || 1003 | 96 | 2 || 1004 | 96 | 2 || 1008 | 94 | 3 || 1005 | 92 | 4 || 1006 | 90 | 5 || 1007 | 90 | 5 || 1001 | 89 | 6 |+--------+-------+------+
3.并列排名,排名有間隔
另外一種排名方式是相同的值排名相同,相同值的下一個(gè)名次應(yīng)該是跳躍整數(shù)值,即排名有間隔。
# 查詢語(yǔ)句SELECT xuehao, score, rank FROM(SELECT xuehao, score,@curRank := IF(@prevRank = score, @curRank, @incRank) AS rank, @incRank := @incRank + 1, @prevRank := scoreFROM scores_tb, (SELECT @curRank :=0, @prevRank := NULL, @incRank := 1) rORDER BY score desc) s;# 排名結(jié)果+--------+-------+------+| xuehao | score | rank |+--------+-------+------+| 1002 | 99 | 1 || 1003 | 96 | 2 || 1004 | 96 | 2 || 1008 | 94 | 4 || 1005 | 92 | 5 || 1006 | 90 | 6 || 1007 | 90 | 6 || 1001 | 89 | 8 |+--------+-------+------+
上面介紹了三種排名方式,實(shí)現(xiàn)起來(lái)還是比較復(fù)雜的。好在MySQL8.0增加了窗口函數(shù),使用內(nèi)置函數(shù)可以輕松實(shí)現(xiàn)上述排名。
MySQL8.0 利用窗口函數(shù)實(shí)現(xiàn)排名
MySQL8.0中可以利用 ROW_NUMBER(),DENSE_RANK(),RANK() 三個(gè)窗口函數(shù)實(shí)現(xiàn)上述三種排名,需要注意的一點(diǎn)是as后的別名,千萬(wàn)不要與前面的函數(shù)名重名,否則會(huì)報(bào)錯(cuò),下面給出這三種函數(shù)實(shí)現(xiàn)排名的案例:
# 三條語(yǔ)句對(duì)于上面三種排名select xuehao,score, ROW_NUMBER() OVER(order by score desc) as row_r from scores_tb;select xuehao,score, DENSE_RANK() OVER(order by score desc) as dense_r from scores_tb;select xuehao,score, RANK() over(order by score desc) as r from scores_tb;# 一條語(yǔ)句也可以查詢出不同排名SELECT xuehao,score, ROW_NUMBER() OVER w AS ’row_r’, DENSE_RANK() OVER w AS ’dense_r’, RANK() OVER w AS ’r’FROM `scores_tb`WINDOW w AS (ORDER BY `score` desc);# 排名結(jié)果+--------+-------+-------+---------+---+| xuehao | score | row_r | dense_r | r |+--------+-------+-------+---------+---+| 1002 | 99 | 1 | 1 | 1 || 1003 | 96 | 2 | 2 | 2 || 1004 | 96 | 3 | 2 | 2 || 1008 | 94 | 4 | 3 | 4 || 1005 | 92 | 5 | 4 | 5 || 1006 | 90 | 6 | 5 | 6 || 1007 | 90 | 7 | 5 | 6 || 1001 | 89 | 8 | 6 | 8 |+--------+-------+-------+---------+---+
總結(jié):
本文給出三種不同場(chǎng)景下實(shí)現(xiàn)統(tǒng)計(jì)排名的SQL,可以根據(jù)不同業(yè)務(wù)需求選取合適的排名方案。對(duì)比MySQL8.0,發(fā)現(xiàn)利用窗口函數(shù)可以更輕松實(shí)現(xiàn)排名,其實(shí)業(yè)務(wù)需求遠(yuǎn)遠(yuǎn)比我們舉的示例要復(fù)雜許多,用SQL實(shí)現(xiàn)此類業(yè)務(wù)需求還是需要慢慢積累的。
以上就是總結(jié)幾種MySQL中常見(jiàn)的排名問(wèn)題的詳細(xì)內(nèi)容,更多關(guān)于MySQL 排名的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. ACCESS轉(zhuǎn)SQL數(shù)據(jù)庫(kù)相關(guān)的幾個(gè)技能2. MySQL中InnoDB和MyISAM類型的差別3. sql server 災(zāi)難恢復(fù)4. 淺談SELECT?*會(huì)導(dǎo)致查詢效率低的原因5. Mybatis自關(guān)聯(lián)查詢一對(duì)多查詢的實(shí)現(xiàn)示例6. mysql8.0.20數(shù)據(jù)目錄遷移的方法7. 講解SQL Server數(shù)據(jù)庫(kù)備份的多種方式8. SQLite教程(五):索引和數(shù)據(jù)分析/清理9. 如何在SQL Server 2005中為安裝程序增加計(jì)數(shù)器注冊(cè)表項(xiàng)值10. DB2數(shù)據(jù)庫(kù)部分日常實(shí)用操作
